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