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