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