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