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