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