merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / frmedt / feshview.cxx
blobe8c849cee09767d5bba9d692b3848b77d5299411
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 _FESHVIEW_ONLY_INLINE_NEEDED
38 #endif
40 #include <svx/svdobj.hxx>
41 #include <svx/svdouno.hxx>
42 #include <svx/svdoole2.hxx>
43 #include <svx/svdogrp.hxx>
44 #include <svx/svdocirc.hxx>
45 #include <svx/svdopath.hxx>
46 #include <svx/sxciaitm.hxx>
47 #include <svx/xfillit.hxx>
48 #include <svx/svdocapt.hxx>
49 #include <sfx2/app.hxx>
50 #include <svx/boxitem.hxx>
51 #include <svx/opaqitem.hxx>
52 #include <svx/protitem.hxx>
53 #include <svx/svdpage.hxx>
54 #include <svx/svdpagv.hxx>
56 #ifndef _POOLFMT_HRC
57 #include <poolfmt.hrc> // fuer InitFldTypes
58 #endif
59 #include <frmfmt.hxx>
60 #include <frmatr.hxx>
61 #include <fmtfsize.hxx>
62 #include <fmtanchr.hxx>
63 #include <fmtornt.hxx>
64 #include <fmtsrnd.hxx>
65 #include <fmtcntnt.hxx>
66 #include <fmtflcnt.hxx>
67 #include <fmtcnct.hxx>
68 #include <docary.hxx>
69 #include <tblsel.hxx>
70 #include <swtable.hxx>
71 #include <flyfrms.hxx>
72 #include "fesh.hxx"
73 #include "rootfrm.hxx"
74 #include "pagefrm.hxx"
75 #include "sectfrm.hxx"
76 #include "doc.hxx"
77 #include "dview.hxx"
78 #include "dflyobj.hxx"
79 #include "dcontact.hxx"
80 #include "viewimp.hxx"
81 #include "flyfrm.hxx"
82 #include "pam.hxx"
83 #include "ndole.hxx"
84 #include "ndgrf.hxx"
85 #include "ndtxt.hxx"
86 #include "viewopt.hxx" // fuer GetHTMLMode
87 #include "swundo.hxx"
88 #include "notxtfrm.hxx"
89 #include "txtfrm.hxx"
90 #include "txatbase.hxx"
91 #include "mdiexp.hxx" // fuer Update der Statuszeile bei drag
92 // OD 2004-05-24 #i28701#
93 #include <sortedobjs.hxx>
94 // --> OD 2006-03-06 #125892#
95 #include <HandleAnchorNodeChg.hxx>
96 // <--
97 #include <basegfx/polygon/b2dpolygon.hxx>
99 #define SCROLLVAL 75
101 using namespace com::sun::star;
103 //Tattergrenze fuer Drawing-SS
104 #define MINMOVE ((USHORT)GetOut()->PixelToLogic(Size(Imp()->GetDrawView()->GetMarkHdlSizePixel()/2,0)).Width())
106 SwFlyFrm *GetFlyFromMarked( const SdrMarkList *pLst, ViewShell *pSh )
108 if ( !pLst )
109 pLst = pSh->HasDrawView() ? &pSh->Imp()->GetDrawView()->GetMarkedObjectList():0;
111 if ( pLst && pLst->GetMarkCount() == 1 )
113 SdrObject *pO = pLst->GetMark( 0 )->GetMarkedSdrObj();
114 if ( pO->ISA(SwVirtFlyDrawObj) )
115 return ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
117 return 0;
120 void lcl_GrabCursor( SwFEShell* pSh, SwFlyFrm* pOldSelFly)
122 const SwFrmFmt *pFlyFmt = pSh->SelFlyGrabCrsr();
123 if( pFlyFmt && !pSh->ActionPend() &&
124 (!pOldSelFly || pOldSelFly->GetFmt() != pFlyFmt) )
126 // dann das evt. gesetzte Macro rufen
127 pSh->GetFlyMacroLnk().Call( (void*)pFlyFmt );
128 extern BOOL bNoInterrupt; // in swapp.cxx
129 // wir in dem Makro ein Dialog gestartet, dann kommt das
130 // MouseButtonUp zu diesem und nicht zu uns. Dadurch ist
131 // Flag bei uns immer gesetzt und schaltet nie die auf die
132 // entsp. Shell um !!!!!!!
133 bNoInterrupt = FALSE;
135 else if( !pFlyFmt || RES_DRAWFRMFMT == pFlyFmt->Which() )
137 // --> OD 2007-07-25 #136039#
138 // assure consistent cursor
139 pSh->KillPams();
140 pSh->ClearMark();
141 // <--
142 pSh->SetCrsr( pSh->Imp()->GetDrawView()->GetAllMarkedRect().TopLeft(), TRUE);
146 /*************************************************************************
148 |* SwFEShell::SelectObj()
150 |* Ersterstellung MA 16. Nov. 92
151 |* Letzte Aenderung MA 22. Oct. 96
153 *************************************************************************/
155 BOOL SwFEShell::SelectObj( const Point& rPt, BYTE nFlag, SdrObject *pObj )
157 SwDrawView *pDView = Imp()->GetDrawView();
158 if(!pDView)
159 return sal_False;
160 SET_CURR_SHELL( this );
161 StartAction(); //Aktion ist Notwendig, damit nicht mehrere
162 //AttrChgdNotify (etwa durch Unmark->MarkListHasChgd)
163 //durchkommen
165 const SdrMarkList &rMrkList = pDView->GetMarkedObjectList();
166 const BOOL bHadSelection = rMrkList.GetMarkCount() ? TRUE : FALSE;
167 const BOOL bAddSelect = 0 != (SW_ADD_SELECT & nFlag);
168 const BOOL bEnterGroup = 0 != (SW_ENTER_GROUP & nFlag);
169 SwFlyFrm* pOldSelFly = 0;
170 const Point aOldPos( pDView->GetAllMarkedRect().TopLeft() );
172 if( bHadSelection )
174 //Unmark rufen wenn !bAddSelect oder wenn ein Fly selektiert ist.
175 BOOL bUnmark = !bAddSelect;
177 if ( rMrkList.GetMarkCount() == 1 )
179 //Wenn ein Fly selektiert ist, so muss er erst deselektiert werden.
180 pOldSelFly = ::GetFlyFromMarked( &rMrkList, this );
181 if ( pOldSelFly )
183 const USHORT nType = GetCntType();
184 if( nType != CNT_TXT || (SW_LEAVE_FRAME & nFlag) ||
185 ( pOldSelFly->GetFmt()->GetProtect().IsCntntProtected()
186 && !IsReadOnlyAvailable() ))
188 //Wenn ein Fly deselektiert wird, der Grafik, Ole o.ae.
189 //enthaelt, so muss der Crsr aus diesem entfernt werden.
190 //Desgleichen wenn ein Fly mit geschuetztem Inhalt deselektiert
191 //wird. Der Einfachheit halber wire der Crsr 'grad so neben die
192 //linke obere Ecke gesetzt.
193 Point aPt( pOldSelFly->Frm().Pos() );
194 aPt.X() -= 1;
195 BOOL bUnLockView = !IsViewLocked();
196 LockView( TRUE );
197 SetCrsr( aPt, TRUE );
198 if( bUnLockView )
199 LockView( FALSE );
201 if ( nType & CNT_GRF &&
202 ((SwNoTxtFrm*)pOldSelFly->Lower())->HasAnimation() )
204 GetWin()->Invalidate( pOldSelFly->Frm().SVRect() );
206 bUnmark = TRUE;
209 if ( bUnmark )
210 pDView->UnmarkAll();
212 else
214 KillPams();
215 ClearMark();
218 if ( pObj )
220 ASSERT( !bEnterGroup, "SW_ENTER_GROUP is not supported" );
221 pDView->MarkObj( pObj, Imp()->GetPageView() );
223 else
225 pDView->MarkObj( rPt, MINMOVE, bAddSelect, bEnterGroup );
228 const BOOL bRet = 0 != rMrkList.GetMarkCount();
230 if ( rMrkList.GetMarkCount() > 1 )
232 //Ganz dumm ist es, wenn Zeichenobjekte Selektiert waren und
233 //nun ein Fly hinzuselektiert wird.
234 for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
236 SdrObject *pTmpObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
237 BOOL bForget = pTmpObj->ISA(SwVirtFlyDrawObj);
238 if( bForget )
240 pDView->UnmarkAll();
241 if ( pTmpObj )
242 pDView->MarkObj( pTmpObj, Imp()->GetPageView(), bAddSelect, bEnterGroup );
243 else
244 pDView->MarkObj( rPt, MINMOVE );
245 break;
250 if ( bRet )
252 ::lcl_GrabCursor(this, pOldSelFly);
253 if ( GetCntType() & CNT_GRF )
255 const SwFlyFrm *pTmp = GetFlyFromMarked( &rMrkList, this );
256 ASSERT( pTmp, "Graphic without Fly" );
257 if ( ((SwNoTxtFrm*)pTmp->Lower())->HasAnimation() )
258 ((SwNoTxtFrm*)pTmp->Lower())->StopAnimation( GetOut() );
261 else if ( !pOldSelFly && bHadSelection )
262 SetCrsr( aOldPos, TRUE);
264 if( bRet || !bHadSelection )
265 CallChgLnk();
267 // update der Statuszeile
268 ::FrameNotify( this, bRet ? FLY_DRAG_START : FLY_DRAG_END );
270 EndAction();
271 return bRet;
274 /*************************************************************************
276 |* sal_Bool SwFEShell::MoveAnchor( USHORT nDir )
278 |* Created AMA 05/28/2002
279 |* Last modify AMA 05/30/2002
281 |* Description: MoveAnchor( nDir ) looked for an another Anchor for
282 |* the selected drawing object (or fly frame) in the given direction.
283 |* An object "as character" doesn't moves anyway.
284 |* A page bounded object could move to the previous/next page with up/down,
285 |* an object bounded "at paragraph" moves to the previous/next paragraph, too.
286 |* An object bounded "at character" moves to the previous/next paragraph
287 |* with up/down and to the previous/next character with left/right.
288 |* If the anchor for at paragraph/character bounded objects has vertical or
289 |* right_to_left text direction, the directions for up/down/left/right will
290 |* interpreted accordingly.
291 |* An object bounded "at fly" takes the center of the actual anchor and looks
292 |* for the nearest fly frame in the given direction.
294 *************************************************************************/
296 #define LESS_X( aPt1, aPt2, bOld ) ( aPt1.X() < aPt2.X() || \
297 ( aPt1.X() == aPt2.X() && ( aPt1.Y() < aPt2.Y() || \
298 ( aPt1.Y() == aPt2.Y() && bOld ) ) ) )
299 #define LESS_Y( aPt1, aPt2, bOld ) ( aPt1.Y() < aPt2.Y() || \
300 ( aPt1.Y() == aPt2.Y() && ( aPt1.X() < aPt2.X() || \
301 ( aPt1.X() == aPt2.X() && bOld ) ) ) )
303 sal_Bool SwFEShell::MoveAnchor( USHORT nDir )
305 const SdrMarkList* pMrkList;
306 if( !Imp()->GetDrawView() ||
307 0 == (pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList()) ||
308 1 != pMrkList->GetMarkCount())
309 return sal_False;
310 SwFrm* pOld;
311 SwFlyFrm* pFly = NULL;
312 SdrObject *pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
313 if( pObj->ISA(SwVirtFlyDrawObj) )
315 pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
316 pOld = pFly->AnchorFrm();
318 else
319 pOld = ((SwDrawContact*)GetUserCall(pObj))->GetAnchorFrm( pObj );
320 sal_Bool bRet = sal_False;
321 if( pOld )
323 SwFrm* pNew = pOld;
324 // --> OD 2004-07-16 #i28701#
325 SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj );
326 SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
327 SwFmtAnchor aAnch( rFmt.GetAnchor() );
328 RndStdIds nAnchorId = aAnch.GetAnchorId();
329 if ( FLY_IN_CNTNT == nAnchorId )
330 return sal_False;
331 if( pOld->IsVertical() )
333 if( pOld->IsTxtFrm() )
335 switch( nDir ) {
336 case SW_MOVE_UP: nDir = SW_MOVE_LEFT; break;
337 case SW_MOVE_DOWN: nDir = SW_MOVE_RIGHT; break;
338 case SW_MOVE_LEFT: nDir = SW_MOVE_DOWN; break;
339 case SW_MOVE_RIGHT: nDir = SW_MOVE_UP; break;
341 if( pOld->IsRightToLeft() )
343 if( nDir == SW_MOVE_LEFT )
344 nDir = SW_MOVE_RIGHT;
345 else if( nDir == SW_MOVE_RIGHT )
346 nDir = SW_MOVE_LEFT;
350 switch ( nAnchorId ) {
351 case FLY_PAGE:
353 ASSERT( pOld->IsPageFrm(), "Wrong anchor, page exspected." );
354 if( SW_MOVE_UP == nDir )
355 pNew = pOld->GetPrev();
356 else if( SW_MOVE_DOWN == nDir )
357 pNew = pOld->GetNext();
358 if( pNew && pNew != pOld )
360 aAnch.SetPageNum( ((SwPageFrm*)pNew)->GetPhyPageNum() );
361 bRet = sal_True;
363 break;
365 case FLY_AUTO_CNTNT:
367 ASSERT( pOld->IsCntntFrm(), "Wrong anchor, page exspected." );
368 if( SW_MOVE_LEFT == nDir || SW_MOVE_RIGHT == nDir )
370 SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
371 SwTxtNode* pTxtNd = ((SwTxtFrm*)pOld)->GetTxtNode();
372 xub_StrLen nAct = pPos->nContent.GetIndex();
373 if( SW_MOVE_LEFT == nDir )
375 bRet = sal_True;
376 if( nAct )
378 --nAct;
379 pPos->nContent.Assign( pTxtNd, nAct );
381 else
382 nDir = SW_MOVE_UP;
384 else
386 xub_StrLen nMax =
387 ((SwTxtFrm*)pOld)->GetTxtNode()->GetTxt().Len();
388 if( nAct < nMax )
390 ++nAct;
391 bRet = sal_True;
392 pPos->nContent.Assign( pTxtNd, nAct );
394 else
395 nDir = SW_MOVE_DOWN;
398 } // no break!
399 case FLY_AT_CNTNT:
401 ASSERT( pOld->IsCntntFrm(), "Wrong anchor, page exspected." );
402 if( SW_MOVE_UP == nDir )
403 pNew = pOld->FindPrev();
404 else if( SW_MOVE_DOWN == nDir )
405 pNew = pOld->FindNext();
406 if( pNew && pNew != pOld && pNew->IsCntntFrm() )
408 SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
409 SwTxtNode* pTxtNd = ((SwTxtFrm*)pNew)->GetTxtNode();
410 pPos->nNode = *pTxtNd;
411 xub_StrLen nTmp = 0;
412 if( bRet )
414 nTmp = ((SwTxtFrm*)pNew)->GetTxtNode()->GetTxt().Len();
415 if( nTmp )
416 --nTmp;
418 pPos->nContent.Assign( pTxtNd, nTmp );
419 bRet = sal_True;
421 else if( SW_MOVE_UP == nDir || SW_MOVE_DOWN == nDir )
422 bRet = sal_False;
423 break;
425 case FLY_AT_FLY:
427 ASSERT( pOld->IsFlyFrm(), "Wrong anchor, fly frame exspected.");
428 SwPageFrm* pPage = pOld->FindPageFrm();
429 ASSERT( pPage, "Where's my page?" );
430 SwFlyFrm* pNewFly = NULL;
431 if( pPage->GetSortedObjs() )
433 int i;
434 sal_Bool bOld = sal_False;
435 Point aCenter( pOld->Frm().Left() + pOld->Frm().Width()/2,
436 pOld->Frm().Top() + pOld->Frm().Height()/2 );
437 Point aBest;
438 for( i = 0; (USHORT)i<pPage->GetSortedObjs()->Count(); ++i )
440 SwAnchoredObject* pAnchObj =
441 (*pPage->GetSortedObjs())[i];
442 if( pAnchObj->ISA(SwFlyFrm) )
444 SwFlyFrm* pTmp = static_cast<SwFlyFrm*>(pAnchObj);
445 if( pTmp == pOld )
446 bOld = sal_True;
447 else
449 const SwFlyFrm* pCheck = pFly ? pTmp : 0;
450 while( pCheck )
452 if( pCheck == pFly )
453 break;
454 const SwFrm *pNxt = pCheck->GetAnchorFrm();
455 pCheck = pNxt ? pNxt->FindFlyFrm() : NULL;
457 if( pCheck || pTmp->IsProtected() )
458 continue;
459 Point aNew( pTmp->Frm().Left() +
460 pTmp->Frm().Width()/2,
461 pTmp->Frm().Top() +
462 pTmp->Frm().Height()/2 );
463 sal_Bool bAccept = sal_False;
464 switch( nDir ) {
465 case SW_MOVE_RIGHT:
467 bAccept = LESS_X( aCenter, aNew, bOld )
468 && ( !pNewFly ||
469 LESS_X( aNew, aBest, sal_False ) );
470 break;
472 case SW_MOVE_LEFT:
474 bAccept = LESS_X( aNew, aCenter, !bOld )
475 && ( !pNewFly ||
476 LESS_X( aBest, aNew, sal_True ) );
477 break;
479 case SW_MOVE_UP:
481 bAccept = LESS_Y( aNew, aCenter, !bOld )
482 && ( !pNewFly ||
483 LESS_Y( aBest, aNew, sal_True ) );
484 break;
486 case SW_MOVE_DOWN:
488 bAccept = LESS_Y( aCenter, aNew, bOld )
489 && ( !pNewFly ||
490 LESS_Y( aNew, aBest, sal_False ) );
491 break;
494 if( bAccept )
496 pNewFly = pTmp;
497 aBest = aNew;
504 if( pNewFly )
506 SwPosition aPos( *pNewFly->GetFmt()->
507 GetCntnt().GetCntntIdx());
508 aAnch.SetAnchor( &aPos );
509 bRet = sal_True;
511 break;
513 default: break;
515 if( bRet )
517 StartAllAction();
518 // --> OD 2006-02-28 #125892#
519 // handle change of anchor node:
520 // if count of the anchor frame also change, the fly frames have to be
521 // re-created. Thus, delete all fly frames except the <this> before the
522 // anchor attribute is change and re-create them afterwards.
524 SwHandleAnchorNodeChg* pHandleAnchorNodeChg( 0L );
525 SwFlyFrmFmt* pFlyFrmFmt( dynamic_cast<SwFlyFrmFmt*>(&rFmt) );
526 if ( pFlyFrmFmt )
528 pHandleAnchorNodeChg =
529 new SwHandleAnchorNodeChg( *pFlyFrmFmt, aAnch );
531 rFmt.GetDoc()->SetAttr( aAnch, rFmt );
532 delete pHandleAnchorNodeChg;
534 // <--
535 // --> OD 2004-06-24 #i28701# - no call of method
536 // <CheckCharRectAndTopOfLine()> for to-character anchored
537 // Writer fly frame needed. This method call can cause a
538 // format of the anchor frame, which is no longer intended.
539 // Instead clear the anchor character rectangle and
540 // the top of line values for all to-character anchored objects.
541 pAnchoredObj->ClearCharRectAndTopOfLine();
542 EndAllAction();
545 return bRet;
548 /*************************************************************************
550 |* SwFEShell::GetSelFrmType()
552 |* Ersterstellung MA 12. Jan. 93
553 |* Letzte Aenderung JP 19.03.96
555 *************************************************************************/
557 const SdrMarkList* SwFEShell::_GetMarkList() const
559 const SdrMarkList* pMarkList = NULL;
560 if( Imp()->GetDrawView() != NULL )
561 pMarkList = &Imp()->GetDrawView()->GetMarkedObjectList();
562 return pMarkList;
565 USHORT SwFEShell::GetSelFrmType() const
567 USHORT eType;
569 // get marked frame list, and check if anything is selected
570 const SdrMarkList* pMarkList = _GetMarkList();
571 if( pMarkList == NULL || pMarkList->GetMarkCount() == 0 )
572 eType = FRMTYPE_NONE;
573 else
575 // obtain marked item as fly frame; if no fly frame, it must
576 // be a draw object
577 const SwFlyFrm* pFly = ::GetFlyFromMarked(pMarkList, (ViewShell*)this);
578 if ( pFly != NULL )
580 if( pFly->IsFlyLayFrm() )
581 eType = FRMTYPE_FLY_FREE;
582 else if( pFly->IsFlyAtCntFrm() )
583 eType = FRMTYPE_FLY_ATCNT;
584 else
586 ASSERT( pFly->IsFlyInCntFrm(), "Neuer Rahmentyp?" );
587 eType = FRMTYPE_FLY_INCNT;
590 else
591 eType = FRMTYPE_DRAWOBJ;
594 return eType;
597 // #108784# does the draw selection contain a control?
598 bool SwFEShell::IsSelContainsControl() const
600 bool bRet = false;
602 // basically, copy the mechanism from GetSelFrmType(), but call
603 // CheckControl... if you get a drawing object
604 const SdrMarkList* pMarkList = _GetMarkList();
605 if( pMarkList != NULL && pMarkList->GetMarkCount() == 1 )
607 // if we have one marked object, get the SdrObject and check
608 // whether it contains a control
609 const SdrObject* pSdrObject = pMarkList->GetMark( 0 )->GetMarkedSdrObj();
610 bRet = CheckControlLayer( pSdrObject );
612 return bRet;
615 /*************************************************************************
617 |* SwFEShell::Scroll()
619 |* Ersterstellung MA 20. Dec. 94
620 |* Letzte Aenderung MA 27. Jul. 95
622 *************************************************************************/
624 void SwFEShell::ScrollTo( const Point &rPt )
626 const SwRect aRect( rPt, rPt );
627 if ( IsScrollMDI( this, aRect ) &&
628 (!Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() ||
629 Imp()->IsDragPossible( rPt )) )
631 //SwSaveHdl aSave( Imp() );
632 ScrollMDI( this, aRect, SCROLLVAL, SCROLLVAL );
636 /*************************************************************************
638 |* SwFEShell::SetDragMode()
640 |* Ersterstellung MA 30. Jan. 95
641 |* Letzte Aenderung MA 30. Jan. 95
643 *************************************************************************/
645 void SwFEShell::SetDragMode( UINT16 eDragMode )
647 if ( Imp()->HasDrawView() )
648 Imp()->GetDrawView()->SetDragMode( (SdrDragMode)eDragMode );
651 /*************************************************************************
653 |* SwFEShell::BeginDrag()
655 |* Ersterstellung MS 10.06.92
656 |* Letzte Aenderung MA 13. Mar. 96
658 *************************************************************************/
660 long SwFEShell::BeginDrag( const Point* pPt, BOOL )
662 SdrView *pView = Imp()->GetDrawView();
663 if ( pView && pView->AreObjectsMarked() )
665 delete pChainFrom; delete pChainTo; pChainFrom = pChainTo = 0;
666 SdrHdl* pHdl = pView->PickHandle( *pPt );
667 pView->BegDragObj( *pPt, 0 /*GetWin()*/, pHdl );
668 ::FrameNotify( this, FLY_DRAG );
669 return 1;
671 return 0;
673 /*************************************************************************
675 |* SwFEShell::Drag()
677 |* Ersterstellung MS 10.06.92
678 |* Letzte Aenderung MA 13. Mar. 96
680 *************************************************************************/
682 long SwFEShell::Drag( const Point *pPt, BOOL )
684 ASSERT( Imp()->HasDrawView(), "Drag without DrawView?" );
685 if ( Imp()->GetDrawView()->IsDragObj() )
687 ScrollTo( *pPt );
688 Imp()->GetDrawView()->MovDragObj( *pPt );
689 Imp()->GetDrawView()->ShowDragAnchor();
690 ::FrameNotify( this, FLY_DRAG );
691 return 1;
693 return 0;
696 /*************************************************************************
698 |* SwFEShell::EndDrag()
700 |* Ersterstellung MS 10.06.92
701 |* Letzte Aenderung MA 13. Mar. 96
703 *************************************************************************/
705 long SwFEShell::EndDrag( const Point *, BOOL )
707 ASSERT( Imp()->HasDrawView(), "EndDrag without DrawView?" );
708 SdrView *pView = Imp()->GetDrawView();
709 if ( pView->IsDragObj() )
711 //Start-/EndActions nur an der ViewShell aufsetzen
712 ViewShell *pSh = this;
713 do {
714 pSh->StartAction();
715 } while ( this != (pSh = (ViewShell*)pSh->GetNext()) );
717 StartUndo( UNDO_START );
719 //#50778# Bug im Draging: Im StartAction wird ein HideShowXor gerufen.
720 //Im EndDragObj() wird dies unsinniger und faelschlicherweise wieder
721 //Rueckgaengig gemacht. Um Konsistenz herzustellen muessen wir das
722 //Xor also wieder zur Anzeige bringen.
724 // Reanimation from the hack #50778 to fix bug #97057
725 // May be not the best solution, but the one with lowest risc at the moment.
726 //pView->ShowShownXor( GetOut() );
728 pView->EndDragObj();
729 // JP 18.08.95: DrawUndo-Action auf FlyFrames werden nicht gespeichert
730 // Die Fly aendern das Flag
731 GetDoc()->SetNoDrawUndoObj( FALSE );
732 ChgAnchor( 0, TRUE );
734 EndUndo( UNDO_END );
736 do {
737 pSh->EndAction();
738 if( pSh->IsA( TYPE( SwCrsrShell ) ) )
739 ((SwCrsrShell*)pSh)->CallChgLnk();
740 } while ( this != (pSh = (ViewShell*)pSh->GetNext()) );
742 GetDoc()->SetModified();
743 ::FrameNotify( this, FLY_DRAG );
744 return 1;
746 return 0;
749 /*************************************************************************
751 |* SwFEShell::BreakDrag()
753 |* Ersterstellung OM 02. Okt. 95
754 |* Letzte Aenderung OM 02. Okt. 95
756 *************************************************************************/
758 void SwFEShell::BreakDrag()
760 ASSERT( Imp()->HasDrawView(), "BreakDrag without DrawView?" );
761 if ( Imp()->GetDrawView()->IsDragObj() )
762 Imp()->GetDrawView()->BrkDragObj();
763 SetChainMarker();
766 /*************************************************************************
768 |* SwFEShell::SelFlyGrabCrsr()
770 |* Beschreibung Wenn ein Fly selektiert ist, zieht er den Crsr in
771 |* den ersten CntntFrm
772 |* Ersterstellung MA 11. Dec. 92
773 |* Letzte Aenderung MA 07. Oct. 96
775 *************************************************************************/
777 const SwFrmFmt* SwFEShell::SelFlyGrabCrsr()
779 if ( Imp()->HasDrawView() )
781 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
782 SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this );
784 if( pFly )
786 // --> OD 2004-06-11 #i28701# - no format here
787 // pFly->GetAnchorFrm()->Calc();
788 SwCntntFrm *pCFrm = pFly->ContainsCntnt();
789 if ( pCFrm )
791 SwCntntNode *pCNode = pCFrm->GetNode();
792 // --> OD 2007-07-25 #126039#
793 // assure, that the cursor is consistent.
794 KillPams();
795 ClearMark();
796 // <--
797 SwPaM *pCrsr = GetCrsr();
799 pCrsr->GetPoint()->nNode = *pCNode;
800 pCrsr->GetPoint()->nContent.Assign( pCNode, 0 );
802 SwRect& rChrRect = (SwRect&)GetCharRect();
803 rChrRect = pFly->Prt();
804 rChrRect.Pos() += pFly->Frm().Pos();
805 GetCrsrDocPos() = rChrRect.Pos();
807 return pFly->GetFmt();
810 return 0;
814 /*************************************************************************
816 |* SwFEShell::SelectionToTop(), SelectionToBottom()
818 |* Beschreibung Selektion nach oben/unten (Z-Order)
820 |* Ersterstellung MA 05. Nov. 92
821 |* Letzte Aenderung MA 03. Jun. 96
823 *************************************************************************/
825 void lcl_NotifyNeighbours( const SdrMarkList *pLst )
827 //Die Regeln fuer die Ausweichmanoever haben sich veraendert.
828 //1. Die Umgebung des Fly und aller innenliegenden muss benachrichtigt
829 // werden.
830 //2. Der Inhalt des Rahmen selbst muss benachrichtigt werden.
831 //3. Rahmen die dem Rahmen ausweichen bzw. wichen muessen benachrichtigt werden.
832 //4. Auch Zeichenobjekte koennen Rahmen verdraengen
834 for( USHORT j = 0; j < pLst->GetMarkCount(); ++j )
836 SwPageFrm *pPage;
837 BOOL bCheckNeighbours = FALSE;
838 sal_Int16 aHori = text::HoriOrientation::NONE;
839 SwRect aRect;
840 SdrObject *pO = pLst->GetMark( 0 )->GetMarkedSdrObj();
841 if ( pO->ISA(SwVirtFlyDrawObj) )
843 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
845 const SwFmtHoriOrient &rHori = pFly->GetFmt()->GetHoriOrient();
846 aHori = rHori.GetHoriOrient();
847 if( text::HoriOrientation::NONE != aHori && text::HoriOrientation::CENTER != aHori &&
848 pFly->IsFlyAtCntFrm() )
850 bCheckNeighbours = TRUE;
851 pFly->InvalidatePos();
852 pFly->Frm().Pos().Y() += 1;
855 pPage = pFly->FindPageFrm();
856 aRect = pFly->Frm();
858 else
860 SwFrm* pAnch = ( (SwDrawContact*)GetUserCall(pO) )->GetAnchorFrm( pO );
861 if( !pAnch )
862 continue;
863 pPage = pAnch->FindPageFrm();
864 // --> OD 2006-08-15 #i68520# - naming changed
865 aRect = GetBoundRectOfAnchoredObj( pO );
866 // <--
869 sal_uInt32 nCount = pPage->GetSortedObjs() ? pPage->GetSortedObjs()->Count() : 0;
870 for ( sal_uInt32 i = 0; i < nCount; ++i )
872 SwAnchoredObject* pAnchoredObj = (*pPage->GetSortedObjs())[i];
873 if ( !pAnchoredObj->ISA(SwFlyFrm) )
874 continue;
876 SwFlyFrm* pAct = static_cast<SwFlyFrm*>(pAnchoredObj);
877 SwRect aTmpCalcPnt( pAct->Prt() );
878 aTmpCalcPnt += pAct->Frm().Pos();
879 if ( aRect.IsOver( aTmpCalcPnt ) )
881 SwCntntFrm *pCnt = pAct->ContainsCntnt();
882 while ( pCnt )
884 aTmpCalcPnt = pCnt->Prt();
885 aTmpCalcPnt += pCnt->Frm().Pos();
886 if ( aRect.IsOver( aTmpCalcPnt ) )
887 ((SwFrm*)pCnt)->Prepare( PREP_FLY_ATTR_CHG );
888 pCnt = pCnt->GetNextCntntFrm();
891 if ( bCheckNeighbours && pAct->IsFlyAtCntFrm() )
893 const SwFmtHoriOrient &rH = pAct->GetFmt()->GetHoriOrient();
894 if ( rH.GetHoriOrient() == aHori &&
895 pAct->Frm().Top() <= aRect.Bottom() &&
896 pAct->Frm().Bottom() >= aRect.Top() )
898 pAct->InvalidatePos();
899 pAct->Frm().Pos().Y() += 1;
906 void SwFEShell::SelectionToTop( BOOL bTop )
908 ASSERT( Imp()->HasDrawView(), "SelectionToTop without DrawView?" );
909 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
910 ASSERT( rMrkList.GetMarkCount(), "Kein Object Selektiert." );
912 SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this );
913 if ( pFly && pFly->IsFlyInCntFrm() )
914 return;
916 StartAllAction();
917 if ( bTop )
918 Imp()->GetDrawView()->PutMarkedToTop();
919 else
920 Imp()->GetDrawView()->MovMarkedToTop();
921 ::lcl_NotifyNeighbours( &rMrkList );
922 GetDoc()->SetModified();
923 EndAllAction();
926 void SwFEShell::SelectionToBottom( BOOL bBottom )
928 ASSERT( Imp()->HasDrawView(), "SelectionToBottom without DrawView?" );
929 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
930 ASSERT( rMrkList.GetMarkCount(), "Kein Object Selektiert." );
932 SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this );
933 if ( pFly && pFly->IsFlyInCntFrm() )
934 return;
936 StartAllAction();
937 if ( bBottom )
938 Imp()->GetDrawView()->PutMarkedToBtm();
939 else
940 Imp()->GetDrawView()->MovMarkedToBtm();
941 ::lcl_NotifyNeighbours( &rMrkList );
942 GetDoc()->SetModified();
943 EndAllAction();
946 /*************************************************************************
948 |* SwFEShell::GetLayerId()
950 |* Beschreibung Objekt ueber/unter dem Dokument?
951 |* 2 Controls, 1 Heaven, 0 Hell, -1 Uneindeutig
952 |* Ersterstellung MA 20. Dec. 94
953 |* Letzte Aenderung MA 20. Dec. 94
955 *************************************************************************/
957 short SwFEShell::GetLayerId() const
959 short nRet = SHRT_MAX;
960 if ( Imp()->HasDrawView() )
962 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
963 for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
965 const SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
966 if ( nRet == SHRT_MAX )
967 nRet = pObj->GetLayer();
968 else if ( nRet != pObj->GetLayer() )
970 nRet = -1;
971 break;
975 if ( nRet == SHRT_MAX )
976 nRet = -1;
977 return nRet;
980 /*************************************************************************
982 |* SwFEShell::SelectionToHeaven(), SelectionToHell()
984 |* Beschreibung Objekt ueber/unter dem Dokument
985 |* Ersterstellung MA 20. Dec. 94
986 |* Letzte Aenderung AMA 04. Jun. 98
988 *************************************************************************/
989 // OD 25.06.2003 #108784#
990 // Note: only visible objects can be marked. Thus, objects with invisible
991 // layer IDs have not to be considered.
992 // If <SwFEShell> exists, layout exists!!
993 void SwFEShell::ChangeOpaque( SdrLayerID nLayerId )
995 if ( Imp()->HasDrawView() )
997 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
998 const IDocumentDrawModelAccess* pIDDMA = getIDocumentDrawModelAccess();
999 // OD 25.06.2003 #108784# - correct type of <nControls>
1000 for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
1002 SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
1003 // OD 21.08.2003 #i18447# - no change of layer for controls
1004 // or group objects containing controls.
1005 const bool bControlObj = ::CheckControlLayer( pObj );
1006 //if ( pObj->GetLayer() != nLayerId && pObj->GetLayer() != nControls )
1007 if ( !bControlObj && pObj->GetLayer() != nLayerId )
1009 pObj->SetLayer( nLayerId );
1010 InvalidateWindows( SwRect( pObj->GetCurrentBoundRect() ) );
1011 if ( pObj->ISA(SwVirtFlyDrawObj) )
1013 SwFmt *pFmt = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetFmt();
1014 SvxOpaqueItem aOpa( pFmt->GetOpaque() );
1015 aOpa.SetValue( nLayerId == pIDDMA->GetHellId() );
1016 pFmt->SetFmtAttr( aOpa );
1020 GetDoc()->SetModified();
1024 void SwFEShell::SelectionToHeaven()
1026 ChangeOpaque( getIDocumentDrawModelAccess()->GetHeavenId() );
1029 void SwFEShell::SelectionToHell()
1031 ChangeOpaque( getIDocumentDrawModelAccess()->GetHellId() );
1034 /*************************************************************************
1036 |* SwFEShell::IsObjSelected(), IsFrmSelected()
1038 |* Ersterstellung MA 16. Nov. 92
1039 |* Letzte Aenderung MA 17. Jan. 95
1041 *************************************************************************/
1043 USHORT SwFEShell::IsObjSelected() const
1045 if ( IsFrmSelected() || !Imp()->HasDrawView() )
1046 return 0;
1047 else
1048 return USHORT( Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() );
1051 BOOL SwFEShell::IsFrmSelected() const
1053 if ( !Imp()->HasDrawView() )
1054 return FALSE;
1055 else
1056 return 0 != ::GetFlyFromMarked( &Imp()->GetDrawView()->GetMarkedObjectList(),
1057 (ViewShell*)this );
1060 sal_Bool SwFEShell::IsObjSelected( const SdrObject& rObj ) const
1062 if ( IsFrmSelected() || !Imp()->HasDrawView() )
1063 return sal_False;
1064 else
1065 return Imp()->GetDrawView()
1066 ->IsObjMarked( const_cast< SdrObject * >( &rObj ) );
1069 /*************************************************************************
1071 |* SwFEShell::EndTextEdit()
1073 |* Ersterstellung MA 19. Feb. 96
1074 |* Letzte Aenderung MA 19. Feb. 96
1076 *************************************************************************/
1078 void SwFEShell::EndTextEdit()
1080 //Beenden des TextEditModus. Wenn gewuenscht (default wenn das Objekt
1081 //keinen Text mehr enthaelt und keine Attribute traegt) wird das
1082 //Objekt gel�scht. Alle anderen markierten Objekte bleiben erhalten.
1084 ASSERT( Imp()->HasDrawView() && Imp()->GetDrawView()->IsTextEdit(),
1085 "EndTextEdit an no Object" );
1087 StartAllAction();
1088 SdrView *pView = Imp()->GetDrawView();
1089 SdrObject *pObj = pView->GetTextEditObject();
1090 SdrObjUserCall* pUserCall;
1091 if( 0 != ( pUserCall = GetUserCall(pObj) ) )
1093 SdrObject *pTmp = ((SwContact*)pUserCall)->GetMaster();
1094 if( !pTmp )
1095 pTmp = pObj;
1096 pUserCall->Changed( *pTmp, SDRUSERCALL_RESIZE, pTmp->GetLastBoundRect() );
1098 if ( !pObj->GetUpGroup() )
1100 if ( SDRENDTEXTEDIT_SHOULDBEDELETED == pView->SdrEndTextEdit(sal_True) )
1102 if ( pView->GetMarkedObjectList().GetMarkCount() > 1 )
1105 SdrMarkList aSave( pView->GetMarkedObjectList() );
1106 aSave.DeleteMark( aSave.FindObject( pObj ) );
1107 if ( aSave.GetMarkCount() )
1109 pView->UnmarkAll();
1110 pView->MarkObj( pObj, Imp()->GetPageView() );
1112 DelSelectedObj();
1113 if ( aSave.GetMarkCount() )
1115 for ( USHORT i = 0; i < aSave.GetMarkCount(); ++i )
1116 pView->MarkObj( aSave.GetMark( i )->GetMarkedSdrObj(),
1117 Imp()->GetPageView() );
1121 else
1122 DelSelectedObj();
1125 else
1126 pView->SdrEndTextEdit();
1127 EndAllAction();
1130 /*************************************************************************
1132 |* SwFEShell::IsInsideSelectedObj()
1134 |* Ersterstellung MA 16. Nov. 92
1135 |* Letzte Aenderung MA 08. Nov. 96
1137 *************************************************************************/
1139 int SwFEShell::IsInsideSelectedObj( const Point &rPt )
1141 if( Imp()->HasDrawView() )
1143 SwDrawView *pDView = Imp()->GetDrawView();
1145 if( pDView->GetMarkedObjectList().GetMarkCount() &&
1146 pDView->IsMarkedObjHit( rPt ) )
1148 return SDRHIT_OBJECT;
1151 return SDRHIT_NONE;
1154 /*************************************************************************
1156 |* SwFEShell::IsObjSelectable()
1158 |* Ersterstellung MA 16. Nov. 92
1159 |* Letzte Aenderung MA 02. Feb. 95
1161 *************************************************************************/
1163 bool SwFEShell::IsObjSelectable( const Point& rPt )
1165 SET_CURR_SHELL(this);
1166 #ifdef OLD
1167 if( Imp()->HasDrawView() )
1168 return Imp()->GetDrawView()->PickSomething( rPt, MINMOVE );
1169 return 0;
1170 #else
1171 SwDrawView *pDView = Imp()->GetDrawView();
1172 bool bRet = false;
1173 if( pDView )
1175 SdrObject* pObj;
1176 SdrPageView* pPV;
1177 USHORT nOld = pDView->GetHitTolerancePixel();
1178 pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
1180 bRet = 0 != pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMARKABLE );
1181 pDView->SetHitTolerancePixel( nOld );
1183 return bRet;
1184 #endif
1187 // #107513#
1188 // Test if there is a draw object at that position and if it should be selected.
1189 // The 'should' is aimed at Writer text fly frames which may be in front of
1190 // the draw object.
1191 sal_Bool SwFEShell::ShouldObjectBeSelected(const Point& rPt)
1193 SET_CURR_SHELL(this);
1194 SwDrawView *pDrawView = Imp()->GetDrawView();
1195 sal_Bool bRet(sal_False);
1197 if(pDrawView)
1199 SdrObject* pObj;
1200 SdrPageView* pPV;
1201 sal_uInt16 nOld(pDrawView->GetHitTolerancePixel());
1203 pDrawView->SetHitTolerancePixel(pDrawView->GetMarkHdlSizePixel()/2);
1204 bRet = pDrawView->PickObj(rPt, pDrawView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMARKABLE);
1205 pDrawView->SetHitTolerancePixel(nOld);
1207 if(bRet && pObj)
1209 const IDocumentDrawModelAccess* pIDDMA = getIDocumentDrawModelAccess();
1210 if( pObj->GetLayer() == pIDDMA->GetHellId() )
1212 const SwFrm *pPageFrm = GetLayout()->Lower();
1213 while( pPageFrm && !pPageFrm->Frm().IsInside( rPt ) )
1215 if ( rPt.Y() < pPageFrm->Frm().Top() )
1216 pPageFrm = 0;
1217 else
1218 pPageFrm = pPageFrm->GetNext();
1220 if( pPageFrm )
1222 SwRect aTmp( pPageFrm->Prt() );
1223 aTmp += pPageFrm->Frm().Pos();
1224 if( aTmp.IsInside( rPt ) )
1225 return sal_False;
1229 const SdrPage* pPage = pIDDMA->GetDrawModel()->GetPage(0);
1230 // --> FME 2005-04-18 #i20965# Use GetOrdNum() instead of GetOrdNumDirect()
1231 // because ordnums might be wrong
1232 for(sal_uInt32 a(pObj->GetOrdNum() + 1); bRet && a < pPage->GetObjCount(); a++)
1234 // <--
1235 SdrObject *pCandidate = pPage->GetObj(a);
1237 if(pCandidate->ISA(SwVirtFlyDrawObj) && ((SwVirtFlyDrawObj*)pCandidate)->GetCurrentBoundRect().IsInside(rPt))
1239 bRet = sal_False;
1245 return bRet;
1248 /*************************************************************************
1250 |* SwFEShell::GotoObj()
1252 |* Beschreibung Wenn ein Obj selektiert ist, gehen wir von dessen
1253 |* TopLeft aus, andernfalls von der Mitte des aktuellen CharRects.
1254 |* Ersterstellung MA 01. Jun. 95
1255 |* Letzte Aenderung MA 30. Apr. 96
1257 *************************************************************************/
1258 /* -----------------23.09.98 10:29-------------------
1259 * Beinhaltet das Objekt ein Control oder Gruppen,
1260 * die nur aus Controls bestehen
1261 * --------------------------------------------------*/
1262 BOOL lcl_IsControlGroup( const SdrObject *pObj )
1264 BOOL bRet = FALSE;
1265 if(pObj->ISA(SdrUnoObj))
1266 bRet = TRUE;
1267 else if( pObj->ISA( SdrObjGroup ) )
1269 bRet = TRUE;
1270 const SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
1271 for ( USHORT i = 0; i < pLst->GetObjCount(); ++i )
1272 if( !::lcl_IsControlGroup( pLst->GetObj( i ) ) )
1273 return FALSE;
1275 return bRet;
1278 BOOL SwFEShell::GotoObj( BOOL bNext, USHORT /*GOTOOBJ_...*/ eType )
1280 if( !Imp()->HasDrawView() )
1281 return FALSE;
1282 else
1284 const SdrObject *pBest = 0,
1285 *pTop = 0;
1287 const long nTmp = bNext ? LONG_MAX : 0;
1288 Point aBestPos( nTmp, nTmp );
1289 Point aTopPos( nTmp, nTmp );
1290 Point aCurPos;
1291 Point aPos;
1292 BOOL bRet = FALSE;
1293 BOOL bNoDraw = 0 == (GOTOOBJ_DRAW_ANY & eType);
1294 BOOL bNoFly = 0 == (GOTOOBJ_FLY_ANY & eType);
1296 if( !bNoFly && bNoDraw )
1298 SwFlyFrm *pFly = GetCurrFrm( FALSE )->FindFlyFrm();
1299 if( pFly )
1300 pBest = pFly->GetVirtDrawObj();
1302 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1303 SdrPageView* pPV = Imp()->GetDrawView()->GetSdrPageView();
1305 if( !pBest || rMrkList.GetMarkCount() == 1 )
1307 // Ausgangspunkt bestimmen.
1308 SdrObjList* pList = NULL;
1309 if ( rMrkList.GetMarkCount() )
1311 const SdrObject* pStartObj = rMrkList.GetMark(0)->GetMarkedSdrObj();
1312 if( pStartObj->ISA(SwVirtFlyDrawObj) )
1313 aPos = ((SwVirtFlyDrawObj*)pStartObj)->GetFlyFrm()->Frm().Pos();
1314 else
1315 aPos = pStartObj->GetSnapRect().TopLeft();
1317 // If an object inside a group is selected, we want to
1318 // iterate over the group members.
1319 if ( ! pStartObj->GetUserCall() )
1320 pList = pStartObj->GetObjList();
1322 else
1324 // If no object is selected, we check if we just entered a group.
1325 // In this case we want to iterate over the group members.
1326 aPos = GetCharRect().Center();
1327 const SdrObject* pStartObj = pPV ? pPV->GetAktGroup() : 0;
1328 if ( pStartObj && pStartObj->ISA( SdrObjGroup ) )
1329 pList = pStartObj->GetSubList();
1332 if ( ! pList )
1334 // Here we are if
1335 // A No object has been selected and no group has been entered or
1336 // B An object has been selected and it is not inside a group
1337 pList = getIDocumentDrawModelAccess()->GetDrawModel()->GetPage( 0 );
1341 ASSERT( pList, "No object list to iterate" )
1343 const ULONG nObjs = pList->GetObjCount();
1344 for( ULONG nObj = 0; nObj < nObjs; ++nObj )
1346 SdrObject* pObj = pList->GetObj( nObj );
1347 BOOL bFlyFrm = pObj->ISA(SwVirtFlyDrawObj);
1348 if( ( bNoFly && bFlyFrm ) ||
1349 ( bNoDraw && !bFlyFrm ) ||
1350 ( eType == GOTOOBJ_DRAW_SIMPLE && lcl_IsControlGroup( pObj ) ) ||
1351 ( eType == GOTOOBJ_DRAW_CONTROL && !lcl_IsControlGroup( pObj ) ) ||
1352 ( pPV && ! pPV->GetView().IsObjMarkable( pObj, pPV ) ) )
1353 continue;
1354 if( bFlyFrm )
1356 SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pObj;
1357 SwFlyFrm *pFly = pO->GetFlyFrm();
1358 if( GOTOOBJ_FLY_ANY != ( GOTOOBJ_FLY_ANY & eType ) )
1360 switch ( eType )
1362 case GOTOOBJ_FLY_FRM:
1363 if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
1364 continue;
1365 break;
1366 case GOTOOBJ_FLY_GRF:
1367 if ( pFly->Lower() &&
1368 (pFly->Lower()->IsLayoutFrm() ||
1369 !((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode()))
1370 continue;
1371 break;
1372 case GOTOOBJ_FLY_OLE:
1373 if ( pFly->Lower() &&
1374 (pFly->Lower()->IsLayoutFrm() ||
1375 !((SwCntntFrm*)pFly->Lower())->GetNode()->GetOLENode()))
1376 continue;
1377 break;
1380 aCurPos = pFly->Frm().Pos();
1382 else
1383 aCurPos = pObj->GetCurrentBoundRect().TopLeft();
1385 // Sonderfall wenn ein anderes Obj auf selber Y steht.
1386 if( aCurPos != aPos && // nur wenn ich es nicht selber bin
1387 aCurPos.Y() == aPos.Y() && // ist die Y Position gleich
1388 (bNext? (aCurPos.X() > aPos.X()) : // liegt neben mir
1389 (aCurPos.X() < aPos.X())) ) // " reverse
1391 aBestPos = Point( nTmp, nTmp );
1392 for( ULONG i = 0; i < nObjs; ++i )
1394 SdrObject *pTmpObj = pList->GetObj( i );
1395 bFlyFrm = pTmpObj->ISA(SwVirtFlyDrawObj);
1396 if( ( bNoFly && bFlyFrm ) || ( bNoDraw && !bFlyFrm ) )
1397 continue;
1398 if( bFlyFrm )
1400 SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pTmpObj;
1401 aCurPos = pO->GetFlyFrm()->Frm().Pos();
1403 else
1404 aCurPos = pTmpObj->GetCurrentBoundRect().TopLeft();
1406 if( aCurPos != aPos && aCurPos.Y() == aPos.Y() &&
1407 (bNext? (aCurPos.X() > aPos.X()) : // liegt neben mir
1408 (aCurPos.X() < aPos.X())) && // " reverse
1409 (bNext? (aCurPos.X() < aBestPos.X()) : // besser als Beste
1410 (aCurPos.X() > aBestPos.X())) ) // " reverse
1412 aBestPos = aCurPos;
1413 pBest = pTmpObj;
1416 break;
1419 if( (bNext? (aPos.Y() < aCurPos.Y()) : // nur unter mir
1420 (aPos.Y() > aCurPos.Y())) && // " reverse
1421 (bNext? (aBestPos.Y() > aCurPos.Y()) : // naeher drunter
1422 (aBestPos.Y() < aCurPos.Y())) || // " reverse
1423 (aBestPos.Y() == aCurPos.Y() &&
1424 (bNext? (aBestPos.X() > aCurPos.X()) : // weiter links
1425 (aBestPos.X() < aCurPos.X())))) // " reverse
1428 aBestPos = aCurPos;
1429 pBest = pObj;
1432 if( (bNext? (aTopPos.Y() > aCurPos.Y()) : // hoeher als Beste
1433 (aTopPos.Y() < aCurPos.Y())) || // " reverse
1434 (aTopPos.Y() == aCurPos.Y() &&
1435 (bNext? (aTopPos.X() > aCurPos.X()) : // weiter links
1436 (aTopPos.X() < aCurPos.X())))) // " reverse
1438 aTopPos = aCurPos;
1439 pTop = pObj;
1442 // leider nichts gefunden
1443 if( (bNext? (aBestPos.X() == LONG_MAX) : (aBestPos.X() == 0)) )
1444 pBest = pTop;
1447 if( pBest )
1449 BOOL bFlyFrm = pBest->ISA(SwVirtFlyDrawObj);
1450 if( bFlyFrm )
1452 SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pBest;
1453 const SwRect& rFrm = pO->GetFlyFrm()->Frm();
1454 SelectObj( rFrm.Pos(), 0, (SdrObject*)pBest );
1455 if( !ActionPend() )
1456 MakeVisible( rFrm );
1458 else
1460 SelectObj( Point(), 0, (SdrObject*)pBest );
1461 if( !ActionPend() )
1462 MakeVisible( pBest->GetCurrentBoundRect() );
1464 CallChgLnk();
1465 bRet = TRUE;
1467 return bRet;
1471 /*************************************************************************
1473 |* SwFEShell::BeginCreate()
1475 |* Ersterstellung MA 20. Dec. 94
1476 |* Letzte Aenderung MA 21. Mar. 95
1478 *************************************************************************/
1480 BOOL SwFEShell::BeginCreate( UINT16 /*SdrObjKind ?*/ eSdrObjectKind, const Point &rPos )
1482 BOOL bRet = FALSE;
1484 if ( !Imp()->HasDrawView() )
1485 Imp()->MakeDrawView();
1487 if ( GetPageNumber( rPos ) )
1489 Imp()->GetDrawView()->SetCurrentObj( eSdrObjectKind );
1490 if ( eSdrObjectKind == OBJ_CAPTION )
1491 bRet = Imp()->GetDrawView()->BegCreateCaptionObj(
1492 rPos, Size( lMinBorder - MINFLY, lMinBorder - MINFLY ),
1493 GetOut() );
1494 else
1495 bRet = Imp()->GetDrawView()->BegCreateObj( rPos, GetOut() );
1497 if ( bRet )
1499 ::FrameNotify( this, FLY_DRAG_START );
1501 return bRet;
1504 BOOL SwFEShell::BeginCreate( UINT16 /*SdrObjKind ?*/ eSdrObjectKind, UINT32 eObjInventor,
1505 const Point &rPos )
1507 BOOL bRet = FALSE;
1509 if ( !Imp()->HasDrawView() )
1510 Imp()->MakeDrawView();
1512 if ( GetPageNumber( rPos ) )
1514 Imp()->GetDrawView()->SetCurrentObj( eSdrObjectKind, eObjInventor );
1515 bRet = Imp()->GetDrawView()->BegCreateObj( rPos, GetOut() );
1517 if ( bRet )
1518 ::FrameNotify( this, FLY_DRAG_START );
1519 return bRet;
1522 /*************************************************************************
1524 |* SwFEShell::MoveCreate()
1526 |* Ersterstellung MA 20. Dec. 94
1527 |* Letzte Aenderung MA 24. Jan. 95
1529 *************************************************************************/
1531 void SwFEShell::MoveCreate( const Point &rPos )
1533 ASSERT( Imp()->HasDrawView(), "MoveCreate without DrawView?" );
1534 if ( GetPageNumber( rPos ) )
1536 ScrollTo( rPos );
1537 Imp()->GetDrawView()->MovCreateObj( rPos );
1538 ::FrameNotify( this, FLY_DRAG );
1542 /*************************************************************************
1544 |* SwFEShell::EndCreate(), ImpEndCreate()
1546 |* Ersterstellung MA 20. Dec. 94
1547 |* Letzte Aenderung MA 14. Oct. 96
1549 *************************************************************************/
1551 BOOL SwFEShell::EndCreate( UINT16 eSdrCreateCmd )
1553 // JP 18.08.95: Damit das Undo-Object aus der DrawEngine nicht bei uns
1554 // gespeichert wird, (wir erzeugen ein eigenes Undo-Object!) hier kurz
1555 // das Undo abschalten
1556 ASSERT( Imp()->HasDrawView(), "EndCreate without DrawView?" );
1557 if( !Imp()->GetDrawView()->IsGroupEntered() )
1558 GetDoc()->SetNoDrawUndoObj( TRUE );
1559 BOOL bCreate = Imp()->GetDrawView()->EndCreateObj(
1560 SdrCreateCmd( eSdrCreateCmd ) );
1561 GetDoc()->SetNoDrawUndoObj( FALSE );
1563 if ( !bCreate )
1565 ::FrameNotify( this, FLY_DRAG_END );
1566 return FALSE;
1569 if ( (SdrCreateCmd)eSdrCreateCmd == SDRCREATE_NEXTPOINT )
1571 ::FrameNotify( this, FLY_DRAG );
1572 return TRUE;
1574 return ImpEndCreate();
1578 BOOL SwFEShell::ImpEndCreate()
1580 ASSERT( Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1,
1581 "Neues Object nicht selektiert." );
1583 SdrObject& rSdrObj = *Imp()->GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
1585 if( rSdrObj.GetSnapRect().IsEmpty() )
1587 //JP 10.04.95: das Object vergessen wir lieber, fuerht nur
1588 // zu Problemen
1589 Imp()->GetDrawView()->DeleteMarked();
1590 Imp()->GetDrawView()->UnmarkAll();
1591 ::FrameNotify( this, FLY_DRAG_END );
1592 return FALSE;
1595 if( rSdrObj.GetUpGroup() )
1597 Point aTmpPos( rSdrObj.GetSnapRect().TopLeft() );
1598 Point aNewAnchor( rSdrObj.GetUpGroup()->GetAnchorPos() );
1599 // OD 2004-04-05 #i26791# - direct object positioning for group members
1600 rSdrObj.NbcSetRelativePos( aTmpPos - aNewAnchor );
1601 rSdrObj.NbcSetAnchorPos( aNewAnchor );
1602 ::FrameNotify( this, FLY_DRAG );
1603 return TRUE;
1606 LockPaint();
1607 StartAllAction();
1609 Imp()->GetDrawView()->UnmarkAll();
1611 const Rectangle &rBound = rSdrObj.GetSnapRect();
1612 Point aPt( rBound.TopRight() );
1614 //Fremde Identifier sollen in den Default laufen.
1615 //Ueberschneidungen sind moeglich!!
1616 UINT16 nIdent = SdrInventor == rSdrObj.GetObjInventor()
1617 ? rSdrObj.GetObjIdentifier()
1618 : 0xFFFF;
1620 //Default fuer Controls ist Zeichengebunden, Absatzgebunden sonst.
1621 SwFmtAnchor aAnch;
1622 const SwFrm *pAnch = 0;
1623 BOOL bCharBound = FALSE;
1624 if( rSdrObj.ISA( SdrUnoObj ) )
1626 SwPosition aPos( GetDoc()->GetNodes() );
1627 SwCrsrMoveState aState( MV_SETONLYTEXT );
1628 Point aPoint( aPt.X(), aPt.Y() + rBound.GetHeight()/2 );
1629 getIDocumentLayoutAccess()->GetRootFrm()->GetCrsrOfst( &aPos, aPoint, &aState );
1631 //JP 22.01.99: Zeichenbindung ist im ReadnOnly-Inhalt nicht erlaubt
1632 if( !aPos.nNode.GetNode().IsProtect() )
1634 pAnch = aPos.nNode.GetNode().GetCntntNode()->GetFrm( &aPoint, &aPos );
1635 SwRect aTmp;
1636 pAnch->GetCharRect( aTmp, aPos );
1638 //Der Crsr darf nicht zu weit entfernt sein.
1639 bCharBound = TRUE;
1640 Rectangle aRect( aTmp.SVRect() );
1641 aRect.Left() -= MM50*2;
1642 aRect.Top() -= MM50*2;
1643 aRect.Right() += MM50*2;
1644 aRect.Bottom()+= MM50*2;
1646 if( !aRect.IsOver( rBound ) && !::GetHtmlMode( GetDoc()->GetDocShell() ))
1647 bCharBound = FALSE;
1649 //Bindung in Kopf-/Fusszeilen ist ebenfalls nicht erlaubt.
1650 if( bCharBound )
1651 bCharBound = !GetDoc()->IsInHeaderFooter( aPos.nNode );
1653 if( bCharBound )
1655 aAnch.SetType( FLY_IN_CNTNT );
1656 aAnch.SetAnchor( &aPos );
1661 if( !bCharBound )
1663 // OD 16.05.2003 #108784# - allow native drawing objects in header/footer.
1664 // Thus, set <bBodyOnly> to <false> for these objects using value
1665 // of <nIdent> - value <0xFFFF> indicates control objects, which aren't
1666 // allowed in header/footer.
1667 //bool bBodyOnly = OBJ_NONE != nIdent;
1668 bool bBodyOnly = 0xFFFF == nIdent;
1669 bool bAtPage = false;
1670 const SwFrm* pPage = 0;
1671 SwCrsrMoveState aState( MV_SETONLYTEXT );
1672 Point aPoint( aPt );
1673 SwPosition aPos( GetDoc()->GetNodes() );
1674 GetLayout()->GetCrsrOfst( &aPos, aPoint, &aState );
1676 //JP 22.01.99: nicht in ReadnOnly-Inhalt setzen
1677 if( aPos.nNode.GetNode().IsProtect() )
1678 // dann darf er nur seitengebunden sein. Oder sollte man
1679 // die naechste nicht READONLY Position suchen?
1680 bAtPage = true;
1682 pAnch = aPos.nNode.GetNode().GetCntntNode()->GetFrm( &aPoint, 0, FALSE );
1684 if( !bAtPage )
1686 const SwFlyFrm *pTmp = pAnch->FindFlyFrm();
1687 if( pTmp )
1689 const SwFrm* pTmpFrm = pAnch;
1690 SwRect aBound( rBound );
1691 while( pTmp )
1693 if( pTmp->Frm().IsInside( aBound ) )
1695 if( !bBodyOnly || !pTmp->FindFooterOrHeader() )
1696 pPage = pTmpFrm;
1697 break;
1699 pTmp = pTmp->GetAnchorFrm()
1700 ? pTmp->GetAnchorFrm()->FindFlyFrm()
1701 : 0;
1702 pTmpFrm = pTmp;
1706 if( !pPage )
1707 pPage = pAnch->FindPageFrm();
1709 // immer ueber FindAnchor gehen, damit der Frame immer an den
1710 // davorgehen gebunden wird. Beim GetCrsOfst kann man auch zum
1711 // nachfolgenden kommen. DAS IST FALSCH
1712 pAnch = ::FindAnchor( pPage, aPt, bBodyOnly );
1713 aPos.nNode = *((SwCntntFrm*)pAnch)->GetNode();
1715 //JP 22.01.99: nicht in ReadnOnly-Inhalt setzen
1716 if( aPos.nNode.GetNode().IsProtect() )
1717 // dann darf er nur seitengebunden sein. Oder sollte man
1718 // die naechste nicht READONLY Position suchen?
1719 bAtPage = true;
1720 else
1722 aAnch.SetType( FLY_AT_CNTNT );
1723 aAnch.SetAnchor( &aPos );
1727 if( bAtPage )
1729 pPage = pAnch->FindPageFrm();
1731 aAnch.SetType( FLY_PAGE );
1732 aAnch.SetPageNum( pPage->GetPhyPageNum() );
1733 pAnch = pPage; // die Page wird jetzt zum Anker
1737 SfxItemSet aSet( GetDoc()->GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE,
1738 RES_SURROUND, RES_ANCHOR, 0 );
1739 aSet.Put( aAnch );
1741 // OD 2004-03-30 #i26791# - determine relative object position
1742 SwTwips nXOffset;
1743 SwTwips nYOffset = rBound.Top() - pAnch->Frm().Top();
1745 if( pAnch->IsVertical() )
1747 nXOffset = nYOffset;
1748 nYOffset = pAnch->Frm().Left()+pAnch->Frm().Width()-rBound.Right();
1750 else if( pAnch->IsRightToLeft() )
1751 nXOffset = pAnch->Frm().Left()+pAnch->Frm().Width()-rBound.Right();
1752 else
1753 nXOffset = rBound.Left() - pAnch->Frm().Left();
1754 if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() )
1756 SwTxtFrm* pTmp = (SwTxtFrm*)pAnch;
1757 do {
1758 pTmp = pTmp->FindMaster();
1759 ASSERT( pTmp, "Where's my Master?" );
1760 // OD 2004-03-30 #i26791# - correction: add frame area height
1761 // of master frames.
1762 nYOffset += pTmp->IsVertical() ?
1763 pTmp->Frm().Width() : pTmp->Frm().Height();
1764 } while ( pTmp->IsFollow() );
1768 if( OBJ_NONE == nIdent )
1770 //Bei OBJ_NONE wird ein Fly eingefuegt.
1771 const long nWidth = rBound.Right() - rBound.Left();
1772 const long nHeight= rBound.Bottom() - rBound.Top();
1773 aSet.Put( SwFmtFrmSize( ATT_MIN_SIZE, Max( nWidth, long(MINFLY) ),
1774 Max( nHeight, long(MINFLY) )));
1776 SwFmtHoriOrient aHori( nXOffset, text::HoriOrientation::NONE, text::RelOrientation::FRAME );
1777 SwFmtVertOrient aVert( nYOffset, text::VertOrientation::NONE, text::RelOrientation::FRAME );
1778 aSet.Put( SwFmtSurround( SURROUND_PARALLEL ) );
1779 aSet.Put( aHori );
1780 aSet.Put( aVert );
1782 //Schnell noch das Rechteck merken
1783 const SwRect aFlyRect( rBound );
1785 //Erzeugtes Object wegwerfen, so kann der Fly am elegentesten
1786 //ueber vorhandene SS erzeugt werden.
1787 GetDoc()->SetNoDrawUndoObj( TRUE ); // siehe oben
1788 // --> OD 2005-08-08 #i52858# - method name changed
1789 SdrPage *pPg = getIDocumentDrawModelAccess()->GetOrCreateDrawModel()->GetPage( 0 );
1790 // <--
1791 if( !pPg )
1793 SdrModel* pTmpSdrModel = getIDocumentDrawModelAccess()->GetDrawModel();
1794 pPg = pTmpSdrModel->AllocPage( FALSE );
1795 pTmpSdrModel->InsertPage( pPg );
1797 pPg->RecalcObjOrdNums();
1798 SdrObject* pRemovedObject = pPg->RemoveObject( rSdrObj.GetOrdNumDirect() );
1799 SdrObject::Free( pRemovedObject );
1800 GetDoc()->SetNoDrawUndoObj( FALSE );
1802 SwFlyFrm* pFlyFrm;
1803 if( NewFlyFrm( aSet, TRUE ) &&
1804 ::GetHtmlMode( GetDoc()->GetDocShell() ) &&
1805 0 != ( pFlyFrm = FindFlyFrm() ))
1807 SfxItemSet aHtmlSet( GetDoc()->GetAttrPool(), RES_VERT_ORIENT, RES_HORI_ORIENT );
1808 //Horizontale Ausrichtung:
1809 const BOOL bLeftFrm = aFlyRect.Left() <
1810 pAnch->Frm().Left() + pAnch->Prt().Left(),
1811 bLeftPrt = aFlyRect.Left() + aFlyRect.Width() <
1812 pAnch->Frm().Left() + pAnch->Prt().Width()/2;
1813 if( bLeftFrm || bLeftPrt )
1815 aHori.SetHoriOrient( text::HoriOrientation::LEFT );
1816 aHori.SetRelationOrient( bLeftFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA );
1818 else
1820 const BOOL bRightFrm = aFlyRect.Left() >
1821 pAnch->Frm().Left() + pAnch->Prt().Width();
1822 aHori.SetHoriOrient( text::HoriOrientation::RIGHT );
1823 aHori.SetRelationOrient( bRightFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA );
1825 aHtmlSet.Put( aHori );
1826 aVert.SetVertOrient( text::VertOrientation::TOP );
1827 aVert.SetRelationOrient( text::RelOrientation::PRINT_AREA );
1828 aHtmlSet.Put( aVert );
1830 GetDoc()->SetAttr( aHtmlSet, *pFlyFrm->GetFmt() );
1833 else
1835 Point aRelNullPt;
1836 if( OBJ_CAPTION == nIdent )
1837 aRelNullPt = ((SdrCaptionObj&)rSdrObj).GetTailPos();
1838 else
1839 aRelNullPt = rBound.TopLeft();
1841 aSet.Put( aAnch );
1842 aSet.Put( SwFmtSurround( SURROUND_THROUGHT ) );
1843 // OD 2004-03-30 #i26791# - set horizontal position
1844 SwFmtHoriOrient aHori( nXOffset, text::HoriOrientation::NONE, text::RelOrientation::FRAME );
1845 aSet.Put( aHori );
1846 // OD 2004-03-30 #i26791# - set vertical position
1847 if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() )
1849 SwTxtFrm* pTmp = (SwTxtFrm*)pAnch;
1850 do {
1851 pTmp = pTmp->FindMaster();
1852 ASSERT( pTmp, "Where's my Master?" );
1853 nYOffset += pTmp->IsVertical() ?
1854 pTmp->Prt().Width() : pTmp->Prt().Height();
1855 } while ( pTmp->IsFollow() );
1857 SwFmtVertOrient aVert( nYOffset, text::VertOrientation::NONE, text::RelOrientation::FRAME );
1858 aSet.Put( aVert );
1859 SwDrawFrmFmt* pFmt = (SwDrawFrmFmt*)getIDocumentLayoutAccess()->MakeLayoutFmt( RND_DRAW_OBJECT, &aSet );
1860 // --> OD 2004-10-25 #i36010# - set layout direction of the position
1861 pFmt->SetPositionLayoutDir(
1862 text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
1863 // <--
1864 // --> OD 2005-03-11 #i44344#, #i44681# - positioning attributes already set
1865 pFmt->PosAttrSet();
1866 // <--
1868 SwDrawContact *pContact = new SwDrawContact( pFmt, &rSdrObj );
1869 // --> OD 2004-11-22 #i35635#
1870 pContact->MoveObjToVisibleLayer( &rSdrObj );
1871 // <--
1872 if( bCharBound )
1874 ASSERT( aAnch.GetAnchorId() == FLY_IN_CNTNT, "wrong AnchorType" );
1875 SwTxtNode *pNd = aAnch.GetCntntAnchor()->nNode.GetNode().GetTxtNode();
1876 SwFmtFlyCnt aFmt( pFmt );
1877 pNd->InsertItem(aFmt,
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;