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