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