Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <hintids.hxx>
21 : #include <svl/itemiter.hxx>
22 : #include <svtools/imapobj.hxx>
23 : #include <svtools/soerr.hxx>
24 : #include <editeng/protitem.hxx>
25 : #include <svx/svdogrp.hxx>
26 : #include <svx/svdouno.hxx>
27 : #include <svx/fmglob.hxx>
28 : #include <com/sun/star/form/FormButtonType.hpp>
29 : #include <com/sun/star/beans/XPropertySet.hpp>
30 : #include <fmtanchr.hxx>
31 : #include <txtflcnt.hxx>
32 : #include <fmtcntnt.hxx>
33 : #include <fmtornt.hxx>
34 : #include <fmtflcnt.hxx>
35 : #include <fmturl.hxx>
36 : #include <fmtclds.hxx>
37 : #include <fmtfsize.hxx>
38 : #include <docary.hxx>
39 : #include <fesh.hxx>
40 : #include <rootfrm.hxx>
41 : #include <pagefrm.hxx>
42 : #include <cntfrm.hxx>
43 : #include <txtfrm.hxx>
44 : #include <viewimp.hxx>
45 : #include <viscrs.hxx>
46 : #include <doc.hxx>
47 : #include <IDocumentUndoRedo.hxx>
48 : #include <IDocumentState.hxx>
49 : #include <IDocumentLayoutAccess.hxx>
50 : #include <dview.hxx>
51 : #include <dflyobj.hxx>
52 : #include <dcontact.hxx>
53 : #include <frmfmt.hxx>
54 : #include <flyfrm.hxx>
55 : #include <ndtxt.hxx>
56 : #include <edimp.hxx>
57 : #include <swtable.hxx>
58 : #include <mvsave.hxx>
59 : #include <ndgrf.hxx>
60 : #include <flyfrms.hxx>
61 : #include <flypos.hxx>
62 : #include <fldbas.hxx>
63 : #include <fmtfld.hxx>
64 : #include <swundo.hxx>
65 : #include <frame.hxx>
66 : #include <notxtfrm.hxx>
67 : #include <HandleAnchorNodeChg.hxx>
68 : #include <frmatr.hxx>
69 : #include <fmtsrnd.hxx>
70 : #include <ndole.hxx>
71 : #include <editeng/opaqitem.hxx>
72 : #include <fefly.hxx>
73 :
74 : using namespace ::com::sun::star;
75 :
76 : // Based on the request, changes to the specific layouts will be made, to
77 : // fit to the format
78 0 : static bool lcl_SetNewFlyPos( const SwNode& rNode, SwFormatAnchor& rAnchor,
79 : const Point& rPt )
80 : {
81 0 : bool bRet = false;
82 0 : const SwStartNode* pStNode = rNode.FindFlyStartNode();
83 0 : if( pStNode )
84 : {
85 0 : SwPosition aPos( *pStNode );
86 0 : rAnchor.SetAnchor( &aPos );
87 0 : bRet = true;
88 : }
89 : else
90 : {
91 0 : const SwContentNode *pCntNd = rNode.GetContentNode();
92 0 : const SwContentFrm* pCFrm = pCntNd ? pCntNd->getLayoutFrm( pCntNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), &rPt, 0, false ) : 0;
93 0 : const SwPageFrm *pPg = pCFrm ? pCFrm->FindPageFrm() : 0;
94 :
95 0 : rAnchor.SetPageNum( pPg ? pPg->GetPhyPageNum() : 1 );
96 0 : rAnchor.SetType( FLY_AT_PAGE );
97 : }
98 0 : return bRet;
99 : }
100 :
101 5 : static bool lcl_FindAnchorPos(
102 : SwDoc& rDoc,
103 : const Point& rPt,
104 : const SwFrm& rFrm,
105 : SfxItemSet& rSet )
106 : {
107 5 : bool bRet = true;
108 5 : SwFormatAnchor aNewAnch( static_cast<const SwFormatAnchor&>(rSet.Get( RES_ANCHOR )) );
109 5 : RndStdIds nNew = aNewAnch.GetAnchorId();
110 : const SwFrm *pNewAnch;
111 :
112 : //determine new anchor
113 5 : Point aTmpPnt( rPt );
114 5 : switch( nNew )
115 : {
116 : case FLY_AS_CHAR: // also include this?
117 : case FLY_AT_PARA:
118 : case FLY_AT_CHAR: // LAYER_IMPL
119 : {
120 : // starting from the upper-left corner of the Fly,
121 : // search nearest ContentFrm
122 2 : const SwFrm* pFrm = rFrm.IsFlyFrm() ? static_cast<const SwFlyFrm&>(rFrm).GetAnchorFrm()
123 2 : : &rFrm;
124 1 : pNewAnch = ::FindAnchor( pFrm, aTmpPnt );
125 1 : if( pNewAnch->IsProtected() )
126 : {
127 0 : bRet = false;
128 0 : break;
129 : }
130 :
131 1 : SwPosition aPos( *static_cast<const SwContentFrm*>(pNewAnch)->GetNode() );
132 1 : if ((FLY_AT_CHAR == nNew) || (FLY_AS_CHAR == nNew))
133 : {
134 : // textnode should be found, as only in those
135 : // a content bound frame can be anchored
136 1 : SwCrsrMoveState aState( MV_SETONLYTEXT );
137 1 : aTmpPnt.setX(aTmpPnt.getX() - 1); // do not land in the fly!
138 1 : if( !pNewAnch->GetCrsrOfst( &aPos, aTmpPnt, &aState ) )
139 : {
140 0 : SwContentNode* pCNd = const_cast<SwContentFrm*>(static_cast<const SwContentFrm*>(pNewAnch))->GetNode();
141 0 : if( pNewAnch->Frm().Bottom() < aTmpPnt.Y() )
142 0 : pCNd->MakeStartIndex( &aPos.nContent );
143 : else
144 0 : pCNd->MakeEndIndex( &aPos.nContent );
145 : }
146 : else
147 : {
148 1 : if ( SwCrsrShell::PosInsideInputField( aPos ) )
149 : {
150 0 : aPos.nContent = SwCrsrShell::StartOfInputFieldAtPos( aPos );
151 : }
152 : }
153 : }
154 1 : aNewAnch.SetAnchor( &aPos );
155 : }
156 1 : break;
157 :
158 : case FLY_AT_FLY: // LAYER_IMPL
159 : {
160 : // starting from the upper-left corner of the Fly
161 : // search nearest SwFlyFrm
162 0 : SwCrsrMoveState aState( MV_SETONLYTEXT );
163 0 : SwPosition aPos( rDoc.GetNodes() );
164 0 : aTmpPnt.setX(aTmpPnt.getX() - 1); // do not land in the fly!
165 0 : rDoc.getIDocumentLayoutAccess().GetCurrentLayout()->GetCrsrOfst( &aPos, aTmpPnt, &aState );
166 : pNewAnch = ::FindAnchor(
167 0 : aPos.nNode.GetNode().GetContentNode()->getLayoutFrm( rFrm.getRootFrm(), 0, 0, false ),
168 0 : aTmpPnt )->FindFlyFrm();
169 :
170 0 : if( pNewAnch && &rFrm != pNewAnch && !pNewAnch->IsProtected() )
171 : {
172 0 : aPos.nNode = *static_cast<const SwFlyFrm*>(pNewAnch)->GetFormat()->GetContent().
173 0 : GetContentIdx();
174 0 : aNewAnch.SetAnchor( &aPos );
175 0 : break;
176 0 : }
177 : }
178 :
179 0 : aNewAnch.SetType( nNew = FLY_AT_PAGE );
180 : // no break
181 :
182 : case FLY_AT_PAGE:
183 4 : pNewAnch = rFrm.FindPageFrm();
184 4 : aNewAnch.SetPageNum( pNewAnch->GetPhyPageNum() );
185 4 : break;
186 :
187 : default:
188 : OSL_ENSURE( false, "Falsche ID fuer neuen Anker." );
189 : }
190 :
191 5 : rSet.Put( aNewAnch );
192 5 : return bRet;
193 : }
194 :
195 : //! also used in unoframe.cxx
196 :
197 5 : bool sw_ChkAndSetNewAnchor(
198 : const SwFlyFrm& rFly,
199 : SfxItemSet& rSet )
200 : {
201 5 : const SwFrameFormat& rFormat = *rFly.GetFormat();
202 5 : const SwFormatAnchor &rOldAnch = rFormat.GetAnchor();
203 5 : const RndStdIds nOld = rOldAnch.GetAnchorId();
204 :
205 5 : RndStdIds nNew = static_cast<const SwFormatAnchor&>(rSet.Get( RES_ANCHOR )).GetAnchorId();
206 :
207 5 : if( nOld == nNew )
208 0 : return false;
209 :
210 5 : SwDoc* pDoc = const_cast<SwDoc*>(rFormat.GetDoc());
211 :
212 : #if OSL_DEBUG_LEVEL > 0
213 : OSL_ENSURE( !(nNew == FLY_AT_PAGE &&
214 : (FLY_AT_PARA==nOld || FLY_AT_CHAR==nOld || FLY_AS_CHAR==nOld ) &&
215 : pDoc->IsInHeaderFooter( rOldAnch.GetContentAnchor()->nNode )),
216 : "forbidden anchor change in Head/Foot." );
217 : #endif
218 :
219 5 : return ::lcl_FindAnchorPos( *pDoc, rFly.Frm().Pos(), rFly, rSet );
220 : }
221 :
222 0 : void SwFEShell::SelectFlyFrm( SwFlyFrm& rFrm, bool bNew )
223 : {
224 0 : SET_CURR_SHELL( this );
225 :
226 : // The frame is new, thus select it.
227 : // !! Always select the frame, if it's not selected.
228 : // - it could be a new "old" one because the anchor was changed
229 : // - "old" frames have had to be selected previously otherwise they could
230 : // not have been changed
231 : // The frames should not be selected by the document position, because
232 : // it should have been selected!
233 0 : SwViewShellImp *pImpl = Imp();
234 0 : if( GetWin() && (bNew || !pImpl->GetDrawView()->AreObjectsMarked()) )
235 : {
236 : OSL_ENSURE( rFrm.IsFlyFrm(), "SelectFlyFrm will einen Fly" );
237 :
238 : // nothing to be done if the Fly already was selected
239 0 : if ( FindFlyFrm() == &rFrm )
240 0 : return;
241 :
242 : // assure the anchor is drawn
243 0 : if( rFrm.IsFlyInCntFrm() && rFrm.GetAnchorFrm() )
244 0 : rFrm.GetAnchorFrm()->SetCompletePaint();
245 :
246 0 : if( pImpl->GetDrawView()->AreObjectsMarked() )
247 0 : pImpl->GetDrawView()->UnmarkAll();
248 :
249 0 : pImpl->GetDrawView()->MarkObj( rFrm.GetVirtDrawObj(),
250 0 : pImpl->GetPageView(), false, false );
251 0 : KillPams();
252 0 : ClearMark();
253 0 : SelFlyGrabCrsr();
254 0 : }
255 : }
256 :
257 : // returns a Fly if one is selected
258 1804 : SwFlyFrm *SwFEShell::FindFlyFrm() const
259 : {
260 1804 : if ( Imp()->HasDrawView() )
261 : {
262 : // A Fly is only accessible if it is selected
263 1804 : const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
264 1804 : if( rMrkList.GetMarkCount() != 1 )
265 1801 : return 0;
266 :
267 3 : SdrObject *pO = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
268 3 : return ( pO && pO->ISA(SwVirtFlyDrawObj) ) ? static_cast<SwVirtFlyDrawObj*>(pO)->GetFlyFrm() : 0;
269 : }
270 0 : return 0;
271 : }
272 :
273 : // Returns non-null pointer, if the current Fly could be anchored to another one (so it is inside)
274 0 : const SwFrameFormat* SwFEShell::IsFlyInFly()
275 : {
276 0 : SET_CURR_SHELL( this );
277 :
278 0 : if ( !Imp()->HasDrawView() )
279 0 : return NULL;
280 :
281 0 : const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
282 0 : if ( !rMrkList.GetMarkCount() )
283 : {
284 0 : SwContentFrm *pContent = GetCurrFrm( false );
285 0 : if( !pContent )
286 0 : return NULL;
287 0 : SwFlyFrm *pFly = pContent->FindFlyFrm();
288 0 : if ( !pFly )
289 0 : return NULL;
290 0 : return pFly->GetFormat();
291 : }
292 0 : else if ( rMrkList.GetMarkCount() != 1 ||
293 0 : !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj()) )
294 0 : return NULL;
295 :
296 0 : SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
297 :
298 0 : SwFrameFormat *pFormat = FindFrameFormat( pObj );
299 0 : if( pFormat && FLY_AT_FLY == pFormat->GetAnchor().GetAnchorId() )
300 : {
301 0 : const SwFrm* pFly = pObj->ISA(SwVirtFlyDrawObj) ?
302 0 : static_cast<SwVirtFlyDrawObj*>(pObj)->GetFlyFrm()->GetAnchorFrm() :
303 0 : static_cast<SwDrawContact*>(GetUserCall(pObj))->GetAnchorFrm( pObj );
304 : OSL_ENSURE( pFly, "IsFlyInFly: Where's my anchor?" );
305 : OSL_ENSURE( pFly->IsFlyFrm(), "IsFlyInFly: Funny anchor!" );
306 0 : return static_cast<const SwFlyFrm*>(pFly)->GetFormat();
307 : }
308 :
309 0 : Point aTmpPos = pObj->GetCurrentBoundRect().TopLeft();
310 :
311 : SwFrm *pTextFrm;
312 : {
313 0 : SwCrsrMoveState aState( MV_SETONLYTEXT );
314 0 : SwNodeIndex aSwNodeIndex( GetDoc()->GetNodes() );
315 0 : SwPosition aPos( aSwNodeIndex );
316 0 : Point aPoint( aTmpPos );
317 0 : aPoint.setX(aPoint.getX() - 1); //do not land in the fly!!
318 0 : GetLayout()->GetCrsrOfst( &aPos, aPoint, &aState );
319 : // determine text frame by left-top-corner of object
320 0 : SwContentNode *pNd = aPos.nNode.GetNode().GetContentNode();
321 0 : pTextFrm = pNd ? pNd->getLayoutFrm(GetLayout(), &aTmpPos, 0, false) : NULL;
322 : }
323 0 : const SwFrm *pTmp = pTextFrm ? ::FindAnchor(pTextFrm, aTmpPos) : NULL;
324 0 : const SwFlyFrm *pFly = pTmp ? pTmp->FindFlyFrm() : NULL;
325 0 : if( pFly )
326 0 : return pFly->GetFormat();
327 0 : return NULL;
328 : }
329 :
330 0 : void SwFEShell::SetFlyPos( const Point& rAbsPos )
331 : {
332 0 : SET_CURR_SHELL( this );
333 :
334 : // Determine reference point in document coordinates
335 0 : SwContentFrm *pContent = GetCurrFrm( false );
336 0 : if( !pContent )
337 0 : return;
338 0 : SwFlyFrm *pFly = pContent->FindFlyFrm();
339 0 : if ( !pFly )
340 0 : return;
341 :
342 : //SwSaveHdl aSaveX( Imp() );
343 :
344 : // Set an anchor starting from the absolute position for paragraph bound Flys
345 : // Anchor and new RelPos will be calculated and set by the Fly
346 0 : if ( pFly->IsFlyAtCntFrm() )
347 0 : static_cast<SwFlyAtCntFrm*>(pFly)->SetAbsPos( rAbsPos );
348 : else
349 : {
350 0 : const SwFrm *pAnch = pFly->GetAnchorFrm();
351 0 : Point aOrient( pAnch->Frm().Pos() );
352 :
353 0 : if ( pFly->IsFlyInCntFrm() )
354 0 : aOrient.setX(rAbsPos.getX());
355 :
356 : // calculate RelPos.
357 0 : aOrient.setX(rAbsPos.getX() - aOrient.getX());
358 0 : aOrient.setY(rAbsPos.getY() - aOrient.getY());
359 0 : pFly->ChgRelPos( aOrient );
360 : }
361 0 : CallChgLnk(); // call the AttrChangeNotify on the UI-side.
362 : }
363 :
364 0 : Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt )
365 : {
366 0 : Point aRet;
367 :
368 0 : SET_CURR_SHELL( this );
369 :
370 0 : if ( !Imp()->HasDrawView() )
371 0 : return aRet;
372 :
373 0 : const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
374 0 : if ( rMrkList.GetMarkCount() != 1 ||
375 0 : !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj()) )
376 0 : return aRet;
377 :
378 0 : SdrObject* pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
379 : // #i28701#
380 0 : SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj );
381 0 : SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat();
382 0 : const RndStdIds nAnchorId = rFormat.GetAnchor().GetAnchorId();
383 :
384 0 : if ( FLY_AS_CHAR == nAnchorId )
385 0 : return aRet;
386 :
387 0 : bool bFlyFrame = pObj->ISA(SwVirtFlyDrawObj);
388 :
389 0 : SwFlyFrm* pFly = 0L;
390 0 : const SwFrm* pFooterOrHeader = NULL;
391 :
392 0 : if( bFlyFrame )
393 : {
394 : // Calculate reference point in document coordinates
395 0 : SwContentFrm *pContent = GetCurrFrm( false );
396 0 : if( !pContent )
397 0 : return aRet;
398 0 : pFly = pContent->FindFlyFrm();
399 0 : if ( !pFly )
400 0 : return aRet;
401 0 : const SwFrm* pOldAnch = pFly->GetAnchorFrm();
402 0 : if( !pOldAnch )
403 0 : return aRet;
404 0 : if ( FLY_AT_PAGE != nAnchorId )
405 : {
406 0 : pFooterOrHeader = pContent->FindFooterOrHeader();
407 : }
408 : }
409 : // set <pFooterOrHeader> also for drawing
410 : // objects, but not for control objects.
411 : // Necessary for moving 'anchor symbol' at the user interface inside header/footer.
412 0 : else if ( !::CheckControlLayer( pObj ) )
413 : {
414 0 : SwContentFrm *pContent = GetCurrFrm( false );
415 0 : if( !pContent )
416 0 : return aRet;
417 0 : pFooterOrHeader = pContent->FindFooterOrHeader();
418 : }
419 :
420 : // Search nearest SwFlyFrm starting from the upper-left corner
421 : // of the fly
422 0 : SwContentFrm *pTextFrm = NULL;
423 : {
424 0 : SwCrsrMoveState aState( MV_SETONLYTEXT );
425 0 : SwPosition aPos( GetDoc()->GetNodes().GetEndOfExtras() );
426 0 : Point aTmpPnt( rAbsPos );
427 0 : GetLayout()->GetCrsrOfst( &aPos, aTmpPnt, &aState );
428 0 : if (aPos.nNode != GetDoc()->GetNodes().GetEndOfExtras().GetIndex()
429 0 : && (nAnchorId != FLY_AT_CHAR || !PosInsideInputField(aPos)))
430 : {
431 0 : SwContentNode* pCNode = aPos.nNode.GetNode().GetContentNode();
432 : assert(pCNode);
433 0 : pTextFrm = pCNode->getLayoutFrm(GetLayout(), 0, &aPos, false);
434 0 : }
435 : }
436 0 : const SwFrm *pNewAnch = NULL;
437 0 : if( pTextFrm != NULL )
438 : {
439 0 : if ( FLY_AT_PAGE == nAnchorId )
440 : {
441 0 : pNewAnch = pTextFrm->FindPageFrm();
442 : }
443 : else
444 : {
445 0 : pNewAnch = ::FindAnchor( pTextFrm, rAbsPos );
446 :
447 0 : if( FLY_AT_FLY == nAnchorId ) // LAYER_IMPL
448 : {
449 0 : pNewAnch = pNewAnch->FindFlyFrm();
450 : }
451 : }
452 : }
453 :
454 0 : if( pNewAnch && !pNewAnch->IsProtected() )
455 : {
456 0 : const SwFlyFrm* pCheck = bFlyFrame ? pNewAnch->FindFlyFrm() : 0;
457 : // If we land inside the frame, make sure
458 : // that the frame does not land inside its own content
459 0 : while( pCheck )
460 : {
461 0 : if( pCheck == pFly )
462 0 : break;
463 0 : const SwFrm *pTmp = pCheck->GetAnchorFrm();
464 0 : pCheck = pTmp ? pTmp->FindFlyFrm() : NULL;
465 : }
466 :
467 : // Do not switch from header/footer to another area,
468 : // do not switch to a header/footer
469 0 : if( !pCheck &&
470 0 : pFooterOrHeader == pNewAnch->FindFooterOrHeader() )
471 : {
472 0 : aRet = pNewAnch->GetFrmAnchorPos( ::HasWrap( pObj ) );
473 :
474 0 : if ( bMoveIt || (nAnchorId == FLY_AT_CHAR) )
475 : {
476 0 : SwFormatAnchor aAnch( rFormat.GetAnchor() );
477 0 : switch ( nAnchorId )
478 : {
479 : case FLY_AT_PARA:
480 : {
481 0 : SwPosition pos = *aAnch.GetContentAnchor();
482 0 : pos.nNode = *pTextFrm->GetNode();
483 0 : pos.nContent.Assign(0,0);
484 0 : aAnch.SetAnchor( &pos );
485 0 : break;
486 : }
487 : case FLY_AT_PAGE:
488 : {
489 : aAnch.SetPageNum( static_cast<const SwPageFrm*>(pNewAnch)->
490 0 : GetPhyPageNum() );
491 0 : break;
492 : }
493 :
494 : case FLY_AT_FLY:
495 : {
496 0 : SwPosition aPos( *static_cast<const SwFlyFrm*>(pNewAnch)->GetFormat()->
497 0 : GetContent().GetContentIdx() );
498 0 : aAnch.SetAnchor( &aPos );
499 0 : break;
500 : }
501 :
502 : case FLY_AT_CHAR:
503 : {
504 0 : SwPosition pos = *aAnch.GetContentAnchor();
505 0 : Point aTmpPnt( rAbsPos );
506 0 : if( pTextFrm->GetCrsrOfst( &pos, aTmpPnt, NULL ) )
507 : {
508 0 : SwRect aTmpRect;
509 0 : pTextFrm->GetCharRect( aTmpRect, pos );
510 0 : aRet = aTmpRect.Pos();
511 : }
512 : else
513 : {
514 0 : pos.nNode = *pTextFrm->GetNode();
515 0 : pos.nContent.Assign(0,0);
516 : }
517 0 : aAnch.SetAnchor( &pos );
518 0 : break;
519 : }
520 : default:
521 0 : break;
522 :
523 : }
524 :
525 0 : if( bMoveIt )
526 : {
527 0 : StartAllAction();
528 : // --> handle change of anchor node:
529 : // if count of the anchor frame also change, the fly frames have to be
530 : // re-created. Thus, delete all fly frames except the <this> before the
531 : // anchor attribute is change and re-create them afterwards.
532 : {
533 0 : SwHandleAnchorNodeChg* pHandleAnchorNodeChg( 0L );
534 0 : SwFlyFrameFormat* pFlyFrameFormat( dynamic_cast<SwFlyFrameFormat*>(&rFormat) );
535 0 : if ( pFlyFrameFormat )
536 : {
537 : pHandleAnchorNodeChg =
538 0 : new SwHandleAnchorNodeChg( *pFlyFrameFormat, aAnch );
539 : }
540 0 : rFormat.GetDoc()->SetAttr( aAnch, rFormat );
541 0 : delete pHandleAnchorNodeChg;
542 : }
543 : // #i28701# - no call of method
544 : // <CheckCharRectAndTopOfLine()> for to-character anchored
545 : // Writer fly frame needed. This method call can cause a
546 : // format of the anchor frame, which is no longer intended.
547 : // Instead clear the anchor character rectangle and
548 : // the top of line values for all to-character anchored objects.
549 0 : pAnchoredObj->ClearCharRectAndTopOfLine();
550 0 : EndAllAction();
551 0 : }
552 : }
553 :
554 0 : SwRect aTmpRect( aRet, rAbsPos );
555 0 : if( aTmpRect.HasArea() )
556 0 : MakeVisible( aTmpRect );
557 : #if OSL_DEBUG_LEVEL > 0
558 : //TODO: That doesn't seem to be intended
559 : if( Color(COL_TRANSPARENT) != GetOut()->GetLineColor() )
560 : {
561 : OSL_FAIL( "Hey, Joe: Where's my Null Pen?" );
562 : GetOut()->SetLineColor( Color(COL_TRANSPARENT) );
563 : }
564 : #endif
565 : }
566 : }
567 :
568 0 : return aRet;
569 : }
570 :
571 0 : const SwFrameFormat *SwFEShell::NewFlyFrm( const SfxItemSet& rSet, bool bAnchValid,
572 : SwFrameFormat *pParent )
573 : {
574 0 : SET_CURR_SHELL( this );
575 0 : StartAllAction();
576 :
577 0 : SwPaM* pCrsr = GetCrsr();
578 0 : const Point aPt( GetCrsrDocPos() );
579 :
580 0 : SwSelBoxes aBoxes;
581 0 : bool bMoveContent = true;
582 0 : if( IsTableMode() )
583 : {
584 0 : GetTableSel( *this, aBoxes );
585 0 : if( !aBoxes.empty() )
586 : {
587 : // Crsr should be removed from the removal area.
588 : // Always put it after/on the table; via the
589 : // document position they will be set to the old
590 : // position
591 0 : ParkCrsr( SwNodeIndex( *aBoxes[0]->GetSttNd() ));
592 :
593 : // #i127787# pCurCrsr will be deleted in ParkCrsr,
594 : // we better get the current pCurCrsr instead of working with the
595 : // deleted one:
596 0 : pCrsr = GetCrsr();
597 : }
598 : else
599 0 : bMoveContent = false;
600 : }
601 0 : else if( !pCrsr->HasMark() && !pCrsr->IsMultiSelection() )
602 0 : bMoveContent = false;
603 :
604 0 : const SwPosition& rPos = *pCrsr->Start();
605 :
606 0 : SwFormatAnchor& rAnch = const_cast<SwFormatAnchor&>(static_cast<const SwFormatAnchor&>(rSet.Get( RES_ANCHOR )));
607 0 : RndStdIds eRndId = rAnch.GetAnchorId();
608 0 : switch( eRndId )
609 : {
610 : case FLY_AT_PAGE:
611 0 : if( !rAnch.GetPageNum() ) //HotFix: Bug in UpdateByExample
612 0 : rAnch.SetPageNum( 1 );
613 0 : break;
614 :
615 : case FLY_AT_FLY:
616 : case FLY_AT_PARA:
617 : case FLY_AT_CHAR:
618 : case FLY_AS_CHAR:
619 0 : if( !bAnchValid )
620 : {
621 0 : if( FLY_AT_FLY != eRndId )
622 : {
623 0 : rAnch.SetAnchor( &rPos );
624 : }
625 0 : else if( lcl_SetNewFlyPos( rPos.nNode.GetNode(), rAnch, aPt ) )
626 : {
627 0 : eRndId = FLY_AT_PAGE;
628 : }
629 : }
630 0 : break;
631 :
632 : default:
633 : OSL_ENSURE( false, "What is the purpose of this Fly?" );
634 0 : break;
635 : }
636 :
637 : SwFlyFrameFormat *pRet;
638 0 : if( bMoveContent )
639 : {
640 0 : GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_INSLAYFMT, NULL );
641 0 : SwFormatAnchor* pOldAnchor = 0;
642 0 : bool bHOriChgd = false, bVOriChgd = false;
643 0 : SwFormatVertOrient aOldV;
644 0 : SwFormatHoriOrient aOldH;
645 :
646 0 : if ( FLY_AT_PAGE != eRndId )
647 : {
648 : // First as with page link. Paragraph/character link on if
649 : // everything was shifted. Then the position is valid!
650 : // JP 13.05.98: if necessary also convert the horizontal/vertical
651 : // orientation, to prevent correction during re-anchoring
652 0 : pOldAnchor = new SwFormatAnchor( rAnch );
653 0 : const_cast<SfxItemSet&>(rSet).Put( SwFormatAnchor( FLY_AT_PAGE, 1 ) );
654 :
655 : const SfxPoolItem* pItem;
656 0 : if( SfxItemState::SET == rSet.GetItemState( RES_HORI_ORIENT, false, &pItem )
657 0 : && text::HoriOrientation::NONE == static_cast<const SwFormatHoriOrient*>(pItem)->GetHoriOrient() )
658 : {
659 0 : bHOriChgd = true;
660 0 : aOldH = *static_cast<const SwFormatHoriOrient*>(pItem);
661 0 : const_cast<SfxItemSet&>(rSet).Put( SwFormatHoriOrient( 0, text::HoriOrientation::LEFT ) );
662 : }
663 0 : if( SfxItemState::SET == rSet.GetItemState( RES_VERT_ORIENT, false, &pItem )
664 0 : && text::VertOrientation::NONE == static_cast<const SwFormatVertOrient*>(pItem)->GetVertOrient() )
665 : {
666 0 : bVOriChgd = true;
667 0 : aOldV = *static_cast<const SwFormatVertOrient*>(pItem);
668 0 : const_cast<SfxItemSet&>(rSet).Put( SwFormatVertOrient( 0, text::VertOrientation::TOP ) );
669 : }
670 : }
671 :
672 0 : pRet = GetDoc()->MakeFlyAndMove( *pCrsr, rSet, &aBoxes, pParent );
673 :
674 0 : KillPams();
675 :
676 0 : if( pOldAnchor )
677 : {
678 0 : if( pRet )
679 : {
680 : // calculate new position
681 : // JP 24.03.97: also go via page links
682 : // chaos::anchor should not lie in the shifted area
683 0 : pRet->DelFrms();
684 :
685 0 : const SwFrm* pAnch = ::FindAnchor( GetLayout(), aPt, false );
686 0 : SwPosition aPos( *static_cast<const SwContentFrm*>(pAnch)->GetNode() );
687 0 : if ( FLY_AS_CHAR == eRndId )
688 : {
689 0 : aPos.nContent.Assign( const_cast<SwContentFrm*>(static_cast<const SwContentFrm*>(pAnch))->GetNode(), 0 );
690 : }
691 0 : pOldAnchor->SetAnchor( &aPos );
692 :
693 : // shifting of table selection is not Undo-capable. therefore
694 : // changing the anchors should not be recorded
695 : bool const bDoesUndo =
696 0 : GetDoc()->GetIDocumentUndoRedo().DoesUndo();
697 0 : SwUndoId nLastUndoId(UNDO_EMPTY);
698 0 : if (bDoesUndo &&
699 0 : GetDoc()->GetIDocumentUndoRedo().GetLastUndoInfo(0,
700 0 : & nLastUndoId))
701 : {
702 0 : if (UNDO_INSLAYFMT == nLastUndoId)
703 : {
704 0 : GetDoc()->GetIDocumentUndoRedo().DoUndo(false);
705 : }
706 : }
707 :
708 0 : const_cast<SfxItemSet&>(rSet).Put( *pOldAnchor );
709 :
710 0 : if( bHOriChgd )
711 0 : const_cast<SfxItemSet&>(rSet).Put( aOldH );
712 0 : if( bVOriChgd )
713 0 : const_cast<SfxItemSet&>(rSet).Put( aOldV );
714 :
715 0 : GetDoc()->SetFlyFrmAttr( *pRet, (SfxItemSet&)rSet );
716 0 : GetDoc()->GetIDocumentUndoRedo().DoUndo(bDoesUndo);
717 : }
718 0 : delete pOldAnchor;
719 : }
720 0 : GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_INSLAYFMT, NULL );
721 : }
722 : else
723 : /* If called from a shell try to propagate an
724 : existing adjust item from rPos to the content node of the
725 : new frame. */
726 0 : pRet = GetDoc()->MakeFlySection( eRndId, &rPos, &rSet, pParent, true );
727 :
728 0 : if( pRet )
729 : {
730 0 : SwFlyFrm* pFrm = pRet->GetFrm( &aPt );
731 0 : if( pFrm )
732 0 : SelectFlyFrm( *pFrm, true );
733 : else
734 : {
735 0 : GetLayout()->SetAssertFlyPages();
736 0 : pRet = 0;
737 : }
738 : }
739 0 : EndAllActionAndCall();
740 :
741 0 : return pRet;
742 : }
743 :
744 0 : void SwFEShell::Insert( const OUString& rGrfName, const OUString& rFltName,
745 : const Graphic* pGraphic,
746 : const SfxItemSet* pFlyAttrSet,
747 : const SfxItemSet* pGrfAttrSet,
748 : SwFrameFormat* pFrameFormat )
749 : {
750 0 : SwFlyFrameFormat* pFormat = 0;
751 0 : SET_CURR_SHELL( this );
752 0 : StartAllAction();
753 0 : SwShellCrsr *pStartCursor = dynamic_cast<SwShellCrsr*>(this->GetSwCrsr());
754 0 : SwShellCrsr *pCursor = pStartCursor;
755 0 : do
756 : {
757 0 : if (!pCursor)
758 0 : break;
759 :
760 : // Has the anchor not been set or been set incompletely?
761 0 : if( pFlyAttrSet )
762 : {
763 : const SfxPoolItem* pItem;
764 0 : if( SfxItemState::SET == pFlyAttrSet->GetItemState( RES_ANCHOR, false,
765 0 : &pItem ) )
766 : {
767 0 : SwFormatAnchor* pAnchor = const_cast<SwFormatAnchor*>(static_cast<const SwFormatAnchor*>(pItem));
768 0 : switch( pAnchor->GetAnchorId())
769 : {
770 : case FLY_AT_PARA:
771 : case FLY_AT_CHAR: // LAYER_IMPL
772 : case FLY_AS_CHAR:
773 0 : if( !pAnchor->GetContentAnchor() )
774 : {
775 0 : pAnchor->SetAnchor( pCursor->GetPoint() );
776 : }
777 0 : break;
778 : case FLY_AT_FLY:
779 0 : if( !pAnchor->GetContentAnchor() )
780 : {
781 0 : lcl_SetNewFlyPos( pCursor->GetNode(),
782 0 : *pAnchor, GetCrsrDocPos() );
783 : }
784 0 : break;
785 : case FLY_AT_PAGE:
786 0 : if( !pAnchor->GetPageNum() )
787 : {
788 : pAnchor->SetPageNum( pCursor->GetPageNum(
789 0 : true, &pCursor->GetPtPos() ) );
790 : }
791 0 : break;
792 : default :
793 0 : break;
794 : }
795 : }
796 : }
797 0 : pFormat = GetDoc()->getIDocumentContentOperations().Insert(*pCursor, rGrfName,
798 : rFltName, pGraphic,
799 : pFlyAttrSet,
800 0 : pGrfAttrSet, pFrameFormat );
801 : OSL_ENSURE( pFormat, "Doc->getIDocumentContentOperations().Insert(notxt) failed." );
802 :
803 0 : pCursor = dynamic_cast<SwShellCrsr*>(pCursor->GetNext());
804 : } while( pCursor != pStartCursor );
805 :
806 0 : EndAllAction();
807 :
808 0 : if( pFormat )
809 : {
810 0 : const Point aPt( GetCrsrDocPos() );
811 0 : SwFlyFrm* pFrm = pFormat->GetFrm( &aPt );
812 :
813 0 : if( pFrm )
814 : {
815 : // fdo#36681: Invalidate the content and layout to refresh
816 : // the picture anchoring properly
817 0 : SwPageFrm* pPageFrm = pFrm->FindPageFrmOfAnchor();
818 0 : pPageFrm->InvalidateFlyLayout();
819 0 : pPageFrm->InvalidateContent();
820 :
821 0 : SelectFlyFrm( *pFrm, true );
822 : }
823 : else
824 0 : GetLayout()->SetAssertFlyPages();
825 0 : }
826 0 : }
827 :
828 0 : SwFlyFrameFormat* SwFEShell::InsertObject( const svt::EmbeddedObjectRef& xObj,
829 : const SfxItemSet* pFlyAttrSet,
830 : const SfxItemSet* pGrfAttrSet,
831 : SwFrameFormat* pFrameFormat )
832 : {
833 0 : SwFlyFrameFormat* pFormat = 0;
834 0 : SET_CURR_SHELL( this );
835 0 : StartAllAction();
836 0 : for(SwPaM& rPaM : GetCrsr()->GetRingContainer())
837 : {
838 0 : pFormat = GetDoc()->getIDocumentContentOperations().Insert(rPaM, xObj,
839 0 : pFlyAttrSet, pGrfAttrSet, pFrameFormat );
840 : OSL_ENSURE( pFormat, "Doc->getIDocumentContentOperations().Insert(notxt) failed." );
841 :
842 : }
843 0 : EndAllAction();
844 :
845 0 : if( pFormat )
846 : {
847 0 : const Point aPt( GetCrsrDocPos() );
848 0 : SwFlyFrm* pFrm = pFormat->GetFrm( &aPt );
849 :
850 0 : if( pFrm )
851 0 : SelectFlyFrm( *pFrm, true );
852 : else
853 0 : GetLayout()->SetAssertFlyPages();
854 : }
855 :
856 0 : return pFormat;
857 : }
858 :
859 0 : void SwFEShell::InsertDrawObj( SdrObject& rDrawObj,
860 : const Point& rInsertPosition )
861 : {
862 0 : SET_CURR_SHELL( this );
863 :
864 0 : SfxItemSet rFlyAttrSet( GetDoc()->GetAttrPool(), aFrameFormatSetRange );
865 0 : rFlyAttrSet.Put( SwFormatAnchor( FLY_AT_PARA ));
866 : // #i89920#
867 0 : rFlyAttrSet.Put( SwFormatSurround( SURROUND_THROUGHT ) );
868 0 : rDrawObj.SetLayer( getIDocumentDrawModelAccess()->GetHeavenId() );
869 :
870 : // find anchor position
871 0 : SwPaM aPam( mpDoc->GetNodes() );
872 : {
873 0 : SwCrsrMoveState aState( MV_SETONLYTEXT );
874 0 : Point aTmpPt( rInsertPosition );
875 0 : GetLayout()->GetCrsrOfst( aPam.GetPoint(), aTmpPt, &aState );
876 0 : const SwFrm* pFrm = aPam.GetContentNode()->getLayoutFrm( GetLayout(), 0, 0, false );
877 0 : const Point aRelPos( rInsertPosition.X() - pFrm->Frm().Left(),
878 0 : rInsertPosition.Y() - pFrm->Frm().Top() );
879 0 : rDrawObj.SetRelativePos( aRelPos );
880 0 : ::lcl_FindAnchorPos( *GetDoc(), rInsertPosition, *pFrm, rFlyAttrSet );
881 : }
882 : // insert drawing object into the document creating a new <SwDrawFrameFormat> instance
883 0 : SwDrawFrameFormat* pFormat = GetDoc()->getIDocumentContentOperations().InsertDrawObj( aPam, rDrawObj, rFlyAttrSet );
884 :
885 : // move object to visible layer
886 0 : SwContact* pContact = static_cast<SwContact*>(rDrawObj.GetUserCall());
887 0 : if ( pContact )
888 : {
889 0 : pContact->MoveObjToVisibleLayer( &rDrawObj );
890 : }
891 :
892 0 : if ( pFormat )
893 : {
894 : // select drawing object
895 0 : Imp()->GetDrawView()->MarkObj( &rDrawObj, Imp()->GetPageView(),
896 0 : false, false );
897 : }
898 : else
899 : {
900 0 : GetLayout()->SetAssertFlyPages();
901 0 : }
902 0 : }
903 :
904 0 : void SwFEShell::GetPageObjs( std::vector<SwFrameFormat*>& rFillArr )
905 : {
906 0 : rFillArr.clear();
907 :
908 0 : for( auto pFormat : *mpDoc->GetSpzFrameFormats() )
909 : {
910 0 : if (FLY_AT_PAGE == pFormat->GetAnchor().GetAnchorId())
911 : {
912 0 : rFillArr.push_back( pFormat );
913 : }
914 : }
915 0 : }
916 :
917 0 : void SwFEShell::SetPageObjsNewPage( std::vector<SwFrameFormat*>& rFillArr, int nOffset )
918 : {
919 0 : if( rFillArr.empty() || !nOffset )
920 0 : return;
921 :
922 0 : StartAllAction();
923 0 : StartUndo();
924 :
925 : long nNewPage;
926 0 : SwRootFrm* pTmpRootFrm = GetLayout();
927 0 : sal_uInt16 nMaxPage = pTmpRootFrm->GetPageNum();
928 0 : bool bTmpAssert = false;
929 0 : for( auto pFormat : rFillArr )
930 : {
931 0 : if( mpDoc->GetSpzFrameFormats()->Contains( pFormat ))
932 : {
933 : // FlyFormat is still valid, therefore process
934 :
935 0 : SwFormatAnchor aNewAnchor( pFormat->GetAnchor() );
936 0 : if ((FLY_AT_PAGE != aNewAnchor.GetAnchorId()) ||
937 0 : 0 >= ( nNewPage = aNewAnchor.GetPageNum() + nOffset ) )
938 : // chaos::Anchor has been changed or invalid page number,
939 : // therefore: do not change!
940 0 : continue;
941 :
942 0 : if( sal_uInt16(nNewPage) > nMaxPage )
943 : {
944 0 : if ( RES_DRAWFRMFMT == pFormat->Which() )
945 : {
946 0 : SwContact *pCon = pFormat->FindContactObj();
947 0 : if( pCon )
948 0 : static_cast<SwDrawContact*>(pCon)->DisconnectFromLayout();
949 : }
950 : else
951 0 : pFormat->DelFrms();
952 0 : bTmpAssert = true;
953 : }
954 0 : aNewAnchor.SetPageNum( sal_uInt16(nNewPage) );
955 0 : mpDoc->SetAttr( aNewAnchor, *pFormat );
956 : }
957 : }
958 :
959 0 : if( bTmpAssert )
960 0 : pTmpRootFrm->SetAssertFlyPages();
961 :
962 0 : EndUndo();
963 0 : EndAllAction();
964 : }
965 :
966 : // All attributes in the "baskets" will be filled with the attributes of the
967 : // current FlyFrms. Attributes which cannot be filled due to being at the
968 : // wrong place or which are ambiguous (multiple selections) will be removed.
969 0 : bool SwFEShell::GetFlyFrmAttr( SfxItemSet &rSet ) const
970 : {
971 0 : SwFlyFrm *pFly = FindFlyFrm();
972 0 : if ( !pFly )
973 : {
974 0 : SwFrm* pCurrFrm( GetCurrFrm() );
975 0 : if ( !pCurrFrm )
976 : {
977 : OSL_FAIL( "<SwFEShell::GetFlyFrmAttr(..)> - missing current frame. This is a serious defect, please inform OD." );
978 0 : return false;
979 : }
980 0 : pFly = GetCurrFrm()->FindFlyFrm();
981 0 : if ( !pFly )
982 : {
983 : OSL_ENSURE( false, "GetFlyFrmAttr, no Fly selected." );
984 0 : return false;
985 : }
986 : }
987 :
988 0 : SET_CURR_SHELL( const_cast<SwViewShell*>(static_cast<SwViewShell const *>(this)) );
989 :
990 0 : if( !rSet.Set( pFly->GetFormat()->GetAttrSet(), true ) )
991 0 : return false;
992 :
993 : // now examine all attributes. Remove forbidden attributes, then
994 : // get all remaining attributes and enter them
995 : const SfxPoolItem* pItem;
996 0 : if( SfxItemState::SET == rSet.GetItemState( RES_ANCHOR, false, &pItem ) )
997 : {
998 0 : const SwFormatAnchor* pAnchor = static_cast<const SwFormatAnchor*>(pItem);
999 0 : RndStdIds eType = pAnchor->GetAnchorId();
1000 :
1001 0 : if ( FLY_AT_PAGE != eType )
1002 : {
1003 : // OD 12.11.2003 #i22341# - content anchor of anchor item is needed.
1004 : // Thus, don't overwrite anchor item by default contructed anchor item.
1005 0 : if ( FLY_AS_CHAR == eType )
1006 : {
1007 0 : rSet.ClearItem( RES_OPAQUE );
1008 0 : rSet.ClearItem( RES_SURROUND );
1009 : }
1010 : }
1011 : }
1012 0 : rSet.SetParent( pFly->GetFormat()->GetAttrSet().GetParent() );
1013 : // attributes must be removed
1014 0 : rSet.ClearItem( RES_FILL_ORDER );
1015 0 : rSet.ClearItem( RES_CNTNT );
1016 : //MA: remove first (Template by example etc.)
1017 0 : rSet.ClearItem( RES_CHAIN );
1018 0 : return true;
1019 : }
1020 :
1021 : // Attributes of the current fly will change.
1022 0 : bool SwFEShell::SetFlyFrmAttr( SfxItemSet& rSet )
1023 : {
1024 0 : SET_CURR_SHELL( this );
1025 0 : bool bRet = false;
1026 :
1027 0 : if( rSet.Count() )
1028 : {
1029 0 : SwFlyFrm *pFly = FindFlyFrm();
1030 0 : if( !pFly )
1031 : {
1032 : OSL_ENSURE( GetCurrFrm(), "Crsr in parking zone" );
1033 0 : pFly = GetCurrFrm()->FindFlyFrm();
1034 : OSL_ENSURE( pFly, "SetFlyFrmAttr, no Fly selected." );
1035 : }
1036 0 : if( pFly )
1037 : {
1038 0 : StartAllAction();
1039 0 : const Point aPt( pFly->Frm().Pos() );
1040 :
1041 0 : if( SfxItemState::SET == rSet.GetItemState( RES_ANCHOR, false ))
1042 0 : sw_ChkAndSetNewAnchor( *pFly, rSet );
1043 0 : SwFlyFrameFormat* pFlyFormat = pFly->GetFormat();
1044 :
1045 0 : if( GetDoc()->SetFlyFrmAttr( *pFlyFormat, rSet ))
1046 : {
1047 0 : bRet = true;
1048 0 : SwFlyFrm* pFrm = pFlyFormat->GetFrm( &aPt );
1049 0 : if( pFrm )
1050 0 : SelectFlyFrm( *pFrm, true );
1051 : else
1052 0 : GetLayout()->SetAssertFlyPages();
1053 : }
1054 :
1055 0 : EndAllActionAndCall();
1056 : }
1057 : }
1058 0 : return bRet;
1059 : }
1060 :
1061 0 : bool SwFEShell::SetDrawingAttr( SfxItemSet& rSet )
1062 : {
1063 0 : bool bRet = false;
1064 0 : SET_CURR_SHELL( this );
1065 0 : if ( !rSet.Count() ||
1066 0 : !Imp()->HasDrawView() )
1067 0 : return bRet;
1068 :
1069 0 : const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1070 0 : if ( rMrkList.GetMarkCount() != 1 )
1071 0 : return bRet;
1072 :
1073 0 : StartUndo();
1074 0 : SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
1075 0 : SwFrameFormat *pFormat = FindFrameFormat( pObj );
1076 0 : StartAllAction();
1077 0 : if( SfxItemState::SET == rSet.GetItemState( RES_ANCHOR, false ))
1078 : {
1079 0 : RndStdIds nNew = static_cast<const SwFormatAnchor&>(rSet.Get( RES_ANCHOR )).GetAnchorId();
1080 0 : if ( nNew != pFormat->GetAnchor().GetAnchorId() )
1081 : {
1082 0 : ChgAnchor( nNew );
1083 : // #i26791# - clear anchor attribute in item set,
1084 : // because method <ChgAnchor(..)> takes care of it.
1085 0 : rSet.ClearItem( RES_ANCHOR );
1086 : }
1087 : }
1088 :
1089 0 : if( GetDoc()->SetFlyFrmAttr( *pFormat, rSet ))
1090 : {
1091 0 : bRet = true;
1092 0 : Point aTmp;
1093 0 : SelectObj( aTmp, 0, pObj );
1094 : }
1095 0 : EndAllActionAndCall();
1096 0 : EndUndo();
1097 0 : return bRet;
1098 : }
1099 :
1100 : // Reset requested attributes or the ones contained in the set.
1101 0 : bool SwFEShell::ResetFlyFrmAttr( sal_uInt16 nWhich, const SfxItemSet* pSet )
1102 : {
1103 0 : bool bRet = false;
1104 :
1105 0 : if( RES_ANCHOR != nWhich && RES_CHAIN != nWhich && RES_CNTNT != nWhich )
1106 : {
1107 0 : SET_CURR_SHELL( this );
1108 :
1109 0 : SwFlyFrm *pFly = FindFlyFrm();
1110 0 : if( !pFly )
1111 : {
1112 : OSL_ENSURE( GetCurrFrm(), "Crsr in parking zone" );
1113 0 : pFly = GetCurrFrm()->FindFlyFrm();
1114 : OSL_ENSURE( pFly, "SetFlyFrmAttr, no Fly selected." );
1115 : }
1116 :
1117 0 : if( pFly )
1118 : {
1119 0 : StartAllAction();
1120 :
1121 0 : if( pSet )
1122 : {
1123 0 : SfxItemIter aIter( *pSet );
1124 0 : const SfxPoolItem* pItem = aIter.FirstItem();
1125 0 : while( pItem )
1126 : {
1127 0 : if( !IsInvalidItem( pItem ) &&
1128 0 : RES_ANCHOR != ( nWhich = pItem->Which() ) &&
1129 0 : RES_CHAIN != nWhich && RES_CNTNT != nWhich )
1130 0 : pFly->GetFormat()->ResetFormatAttr( nWhich );
1131 0 : pItem = aIter.NextItem();
1132 0 : }
1133 : }
1134 : else
1135 0 : pFly->GetFormat()->ResetFormatAttr( nWhich );
1136 :
1137 0 : bRet = true;
1138 0 : EndAllActionAndCall();
1139 0 : GetDoc()->getIDocumentState().SetModified();
1140 0 : }
1141 : }
1142 0 : return bRet;
1143 : }
1144 :
1145 : // Returns frame-format if frame, otherwise 0
1146 1661 : SwFrameFormat* SwFEShell::GetCurFrameFormat() const
1147 : {
1148 1661 : SwFrameFormat* pRet = 0;
1149 1661 : SwLayoutFrm *pFly = FindFlyFrm();
1150 1661 : if( pFly && ( pRet = static_cast<SwFrameFormat*>(pFly->GetFormat()->DerivedFrom()) ) ==
1151 0 : GetDoc()->GetDfltFrameFormat() )
1152 0 : pRet = 0;
1153 1661 : return pRet;
1154 : }
1155 :
1156 0 : void SwFEShell::SetFrameFormat( SwFrameFormat *pNewFormat, bool bKeepOrient, Point* pDocPos )
1157 : {
1158 0 : SwFlyFrm *pFly = 0;
1159 0 : if(pDocPos)
1160 : {
1161 0 : const SwFrameFormat* pFormat = GetFormatFromObj( *pDocPos );
1162 :
1163 0 : if(PTR_CAST(SwFlyFrameFormat, pFormat))
1164 0 : pFly = static_cast<const SwFlyFrameFormat*>(pFormat)->GetFrm();
1165 : }
1166 : else
1167 0 : pFly = FindFlyFrm();
1168 : OSL_ENSURE( pFly, "SetFrameFormat: no frame" );
1169 0 : if( pFly )
1170 : {
1171 0 : StartAllAction();
1172 0 : SET_CURR_SHELL( this );
1173 :
1174 0 : SwFlyFrameFormat* pFlyFormat = pFly->GetFormat();
1175 0 : const Point aPt( pFly->Frm().Pos() );
1176 :
1177 0 : SfxItemSet* pSet = 0;
1178 : const SfxPoolItem* pItem;
1179 0 : if( SfxItemState::SET == pNewFormat->GetItemState( RES_ANCHOR, false, &pItem ))
1180 : {
1181 0 : pSet = new SfxItemSet( GetDoc()->GetAttrPool(), aFrameFormatSetRange );
1182 0 : pSet->Put( *pItem );
1183 0 : if( !sw_ChkAndSetNewAnchor( *pFly, *pSet ))
1184 0 : delete pSet, pSet = 0;
1185 : }
1186 :
1187 0 : if( GetDoc()->SetFrameFormatToFly( *pFlyFormat, *pNewFormat, pSet, bKeepOrient ))
1188 : {
1189 0 : SwFlyFrm* pFrm = pFlyFormat->GetFrm( &aPt );
1190 0 : if( pFrm )
1191 0 : SelectFlyFrm( *pFrm, true );
1192 : else
1193 0 : GetLayout()->SetAssertFlyPages();
1194 : }
1195 0 : delete pSet;
1196 :
1197 0 : EndAllActionAndCall();
1198 : }
1199 0 : }
1200 :
1201 0 : const SwFrameFormat* SwFEShell::GetFlyFrameFormat() const
1202 : {
1203 0 : const SwFlyFrm* pFly = FindFlyFrm();
1204 0 : if ( !pFly )
1205 : {
1206 0 : SwFrm* pCurrFrm = GetCurrFrm();
1207 0 : pFly = pCurrFrm ? pCurrFrm->FindFlyFrm() : 0;
1208 : }
1209 0 : if( pFly )
1210 0 : return pFly->GetFormat();
1211 0 : return 0;
1212 : }
1213 :
1214 4 : SwFrameFormat* SwFEShell::GetFlyFrameFormat()
1215 : {
1216 4 : SwFlyFrm* pFly = FindFlyFrm();
1217 4 : if ( !pFly )
1218 : {
1219 4 : SwFrm* pCurrFrm = GetCurrFrm();
1220 4 : pFly = pCurrFrm ? pCurrFrm->FindFlyFrm() : 0;
1221 : }
1222 4 : if( pFly )
1223 0 : return pFly->GetFormat();
1224 4 : return 0;
1225 : }
1226 :
1227 0 : SwRect SwFEShell::GetFlyRect() const
1228 : {
1229 0 : SwContentFrm *pContent = GetCurrFrm( false );
1230 0 : SwFlyFrm *pFly = pContent ? pContent->FindFlyFrm() : 0;
1231 0 : if ( !pFly )
1232 : {
1233 0 : SwRect aRect;
1234 0 : return aRect;
1235 : }
1236 : else
1237 0 : return pFly->Frm();
1238 : }
1239 :
1240 0 : SwRect SwFEShell::GetObjRect() const
1241 : {
1242 0 : if( Imp()->HasDrawView() )
1243 0 : return Imp()->GetDrawView()->GetAllMarkedRect();
1244 : else
1245 : {
1246 0 : SwRect aRect;
1247 0 : return aRect;
1248 : }
1249 : }
1250 :
1251 0 : void SwFEShell::SetObjRect( const SwRect& rRect )
1252 : {
1253 0 : if ( Imp()->HasDrawView() )
1254 : {
1255 0 : Imp()->GetDrawView()->SetAllMarkedRect( rRect.SVRect() );
1256 0 : CallChgLnk(); // call AttrChangeNotify on the UI-side.
1257 : }
1258 0 : }
1259 :
1260 23 : Size SwFEShell::RequestObjectResize( const SwRect &rRect, const uno::Reference < embed::XEmbeddedObject >& xObj )
1261 : {
1262 23 : Size aResult;
1263 :
1264 23 : SwFlyFrm *pFly = FindFlyFrm( xObj );
1265 23 : if ( !pFly )
1266 : {
1267 0 : aResult = rRect.SSize();
1268 0 : return aResult;
1269 : }
1270 :
1271 23 : aResult = pFly->Prt().SSize();
1272 :
1273 23 : bool bPosProt = pFly->GetFormat()->GetProtect().IsPosProtected();
1274 23 : bool bSizeProt = pFly->GetFormat()->GetProtect().IsSizeProtected();
1275 :
1276 23 : StartAllAction();
1277 :
1278 : // MA we do not allow to clip the Fly, as the OLE server can
1279 : // request various wishes. Clipping is done via the formatting.
1280 : // Correct display is done by scaling.
1281 : // Scaling is done by SwNoTextFrm::Format by calling
1282 : // SwWrtShell::CalcAndSetScale()
1283 23 : if ( rRect.SSize() != pFly->Prt().SSize() && !bSizeProt )
1284 : {
1285 9 : Size aSz( rRect.SSize() );
1286 :
1287 : //JP 28.02.2001: Task 74707 - ask for fly in fly with automatic size
1288 :
1289 : const SwFrm* pAnchor;
1290 : const SwTextNode* pTNd;
1291 : const SwpHints* pHts;
1292 9 : const SwFormatFrmSize& rFrmSz = pFly->GetFormat()->GetFrmSize();
1293 9 : if (m_bCheckForOLEInCaption &&
1294 0 : 0 != rFrmSz.GetWidthPercent() &&
1295 0 : 0 != (pAnchor = pFly->GetAnchorFrm()) &&
1296 0 : pAnchor->IsTextFrm() &&
1297 0 : !pAnchor->GetNext() && !pAnchor->GetPrev() &&
1298 0 : pAnchor->GetUpper()->IsFlyFrm() &&
1299 9 : 0 != ( pTNd = static_cast<const SwTextFrm*>(pAnchor)->GetNode()->GetTextNode()) &&
1300 : 0 != ( pHts = pTNd->GetpSwpHints() ))
1301 : {
1302 : // search for a sequence field:
1303 0 : const size_t nEnd = pHts->Count();
1304 0 : for( size_t n = 0; n < nEnd; ++n )
1305 : {
1306 0 : const SfxPoolItem* pItem = &(*pHts)[ n ]->GetAttr();
1307 0 : if( RES_TXTATR_FIELD == pItem->Which()
1308 0 : && TYP_SEQFLD == static_cast<const SwFormatField*>(pItem)->GetField()->GetTypeId() )
1309 : {
1310 : // sequence field found
1311 0 : SwFlyFrm* pChgFly = const_cast<SwFlyFrm*>(static_cast<const SwFlyFrm*>(pAnchor->GetUpper()));
1312 : // calculate the changed size:
1313 : // width must change, height can change
1314 0 : Size aNewSz( aSz.Width() + pChgFly->Frm().Width() -
1315 0 : pFly->Prt().Width(), aSz.Height() );
1316 :
1317 0 : SwFrameFormat *pFormat = pChgFly->GetFormat();
1318 0 : SwFormatFrmSize aFrmSz( pFormat->GetFrmSize() );
1319 0 : aFrmSz.SetWidth( aNewSz.Width() );
1320 0 : if( ATT_MIN_SIZE != aFrmSz.GetHeightSizeType() )
1321 : {
1322 0 : aNewSz.Height() += pChgFly->Frm().Height() -
1323 0 : pFly->Prt().Height();
1324 0 : if( std::abs( aNewSz.Height() - pChgFly->Frm().Height()) > 1 )
1325 0 : aFrmSz.SetHeight( aNewSz.Height() );
1326 : }
1327 : // via Doc for the Undo!
1328 0 : pFormat->GetDoc()->SetAttr( aFrmSz, *pFormat );
1329 0 : break;
1330 : }
1331 : }
1332 : }
1333 :
1334 : // set the new Size at the fly themself
1335 9 : if ( pFly->Prt().Height() > 0 && pFly->Prt().Width() > 0 )
1336 : {
1337 1 : aSz.Width() += pFly->Frm().Width() - pFly->Prt().Width();
1338 1 : aSz.Height()+= pFly->Frm().Height()- pFly->Prt().Height();
1339 : }
1340 9 : aResult = pFly->ChgSize( aSz );
1341 :
1342 : // if the object changes, the contour is outside the object
1343 : OSL_ENSURE( pFly->Lower()->IsNoTextFrm(), "Request without NoText" );
1344 9 : SwNoTextNode *pNd = static_cast<SwContentFrm*>(pFly->Lower())->GetNode()->GetNoTextNode();
1345 : OSL_ENSURE( pNd, "Request without Node" );
1346 9 : pNd->SetContour( 0 );
1347 9 : ClrContourCache();
1348 : }
1349 :
1350 : // if only the size is to be adjusted, a position is transported with
1351 : // allocated values
1352 23 : Point aPt( pFly->Prt().Pos() );
1353 23 : aPt += pFly->Frm().Pos();
1354 23 : if ( rRect.Top() != LONG_MIN && rRect.Pos() != aPt && !bPosProt )
1355 : {
1356 0 : aPt = rRect.Pos();
1357 0 : aPt.setX(aPt.getX() - pFly->Prt().Left());
1358 0 : aPt.setY(aPt.getY() - pFly->Prt().Top());
1359 :
1360 : // in case of paragraph-bound Flys, starting from the new position,
1361 : // a new anchor is to be set. The anchor and the new RelPos are
1362 : // calculated by the Fly and set
1363 0 : if( pFly->IsFlyAtCntFrm() )
1364 0 : static_cast<SwFlyAtCntFrm*>(pFly)->SetAbsPos( aPt );
1365 : else
1366 : {
1367 0 : const SwFrameFormat *pFormat = pFly->GetFormat();
1368 0 : const SwFormatVertOrient &rVert = pFormat->GetVertOrient();
1369 0 : const SwFormatHoriOrient &rHori = pFormat->GetHoriOrient();
1370 0 : const long lXDiff = aPt.getX() - pFly->Frm().Left();
1371 0 : const long lYDiff = aPt.getY() - pFly->Frm().Top();
1372 0 : const Point aTmp( rHori.GetPos() + lXDiff,
1373 0 : rVert.GetPos() + lYDiff );
1374 0 : pFly->ChgRelPos( aTmp );
1375 : }
1376 : }
1377 :
1378 23 : SwFlyFrameFormat *pFlyFrameFormat = pFly->GetFormat();
1379 : OSL_ENSURE( pFlyFrameFormat, "fly frame format missing!" );
1380 23 : if ( pFlyFrameFormat )
1381 23 : pFlyFrameFormat->SetLastFlyFrmPrtRectPos( pFly->Prt().Pos() ); //stores the value of last Prt rect
1382 :
1383 23 : EndAllAction();
1384 :
1385 23 : return aResult;
1386 : }
1387 :
1388 0 : SwFrameFormat* SwFEShell::WizzardGetFly()
1389 : {
1390 : // do not search the Fly via the layout. Now we can delete a frame
1391 : // without a valid layout. ( e.g. for the wizards )
1392 0 : SwFrameFormats& rSpzArr = *mpDoc->GetSpzFrameFormats();
1393 0 : if( !rSpzArr.empty() )
1394 : {
1395 0 : SwNodeIndex& rCrsrNd = GetCrsr()->GetPoint()->nNode;
1396 0 : if( rCrsrNd.GetIndex() > mpDoc->GetNodes().GetEndOfExtras().GetIndex() )
1397 : // Cursor is in the body area!
1398 0 : return 0;
1399 :
1400 0 : for( auto pFormat : rSpzArr )
1401 : {
1402 0 : const SwNodeIndex* pIdx = pFormat->GetContent( false ).GetContentIdx();
1403 : SwStartNode* pSttNd;
1404 0 : if( pIdx &&
1405 0 : 0 != ( pSttNd = pIdx->GetNode().GetStartNode() ) &&
1406 0 : pSttNd->GetIndex() < rCrsrNd.GetIndex() &&
1407 0 : rCrsrNd.GetIndex() < pSttNd->EndOfSectionIndex() )
1408 : {
1409 : // found: return immediately
1410 0 : return pFormat;
1411 : }
1412 : }
1413 : }
1414 0 : return 0;
1415 : }
1416 :
1417 0 : void SwFEShell::SetFlyName( const OUString& rName )
1418 : {
1419 0 : SwLayoutFrm *pFly = FindFlyFrm();
1420 0 : if( pFly )
1421 0 : GetDoc()->SetFlyName( *static_cast<SwFlyFrameFormat*>(pFly->GetFormat()), rName );
1422 : else {
1423 : OSL_ENSURE( false, "no FlyFrame selected" );
1424 : }
1425 0 : }
1426 :
1427 0 : OUString SwFEShell::GetFlyName() const
1428 : {
1429 0 : SwLayoutFrm *pFly = FindFlyFrm();
1430 0 : if( pFly )
1431 0 : return pFly->GetFormat()->GetName();
1432 :
1433 : OSL_ENSURE( false, "no FlyFrame selected" );
1434 0 : return OUString();
1435 : }
1436 :
1437 0 : const uno::Reference < embed::XEmbeddedObject > SwFEShell::GetOleRef() const
1438 : {
1439 0 : uno::Reference < embed::XEmbeddedObject > xObj;
1440 0 : SwFlyFrm * pFly = FindFlyFrm();
1441 0 : if (pFly && pFly->Lower() && pFly->Lower()->IsNoTextFrm())
1442 : {
1443 0 : SwOLENode *pNd = static_cast<SwNoTextFrm*>(pFly->Lower())->GetNode()->GetOLENode();
1444 0 : if (pNd)
1445 0 : xObj = pNd->GetOLEObj().GetOleRef();
1446 : }
1447 0 : return xObj;
1448 : }
1449 :
1450 0 : OUString SwFEShell::GetUniqueGrfName() const
1451 : {
1452 0 : return GetDoc()->GetUniqueGrfName();
1453 : }
1454 :
1455 1 : const SwFrameFormat* SwFEShell::IsURLGrfAtPos( const Point& rPt, OUString* pURL,
1456 : OUString *pTargetFrameName,
1457 : OUString *pDescription ) const
1458 : {
1459 1 : if( !Imp()->HasDrawView() )
1460 0 : return 0;
1461 :
1462 : SdrObject* pObj;
1463 : SdrPageView* pPV;
1464 1 : const SwFrameFormat* pRet = 0;
1465 1 : SwDrawView *pDView = const_cast<SwDrawView*>(Imp()->GetDrawView());
1466 :
1467 1 : const auto nOld = pDView->GetHitTolerancePixel();
1468 1 : pDView->SetHitTolerancePixel( 2 );
1469 :
1470 1 : if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPV,SdrSearchOptions::PICKMACRO ) &&
1471 0 : pObj->ISA(SwVirtFlyDrawObj) )
1472 : {
1473 0 : SwFlyFrm *pFly = static_cast<SwVirtFlyDrawObj*>(pObj)->GetFlyFrm();
1474 0 : const SwFormatURL &rURL = pFly->GetFormat()->GetURL();
1475 0 : if( !rURL.GetURL().isEmpty() || rURL.GetMap() )
1476 : {
1477 0 : bool bSetTargetFrameName = pTargetFrameName != 0;
1478 0 : bool bSetDescription = pDescription != 0;
1479 0 : if ( rURL.GetMap() )
1480 : {
1481 0 : IMapObject *pObject = pFly->GetFormat()->GetIMapObject( rPt, pFly );
1482 0 : if ( pObject && !pObject->GetURL().isEmpty() )
1483 : {
1484 0 : if( pURL )
1485 0 : *pURL = pObject->GetURL();
1486 0 : if ( bSetTargetFrameName && !pObject->GetTarget().isEmpty() )
1487 : {
1488 0 : bSetTargetFrameName = false;
1489 0 : *pTargetFrameName = pObject->GetTarget();
1490 : }
1491 0 : if ( bSetDescription )
1492 : {
1493 0 : bSetDescription = false;
1494 0 : *pDescription = pObject->GetAltText();
1495 : }
1496 0 : pRet = pFly->GetFormat();
1497 : }
1498 : }
1499 : else
1500 : {
1501 0 : if( pURL )
1502 : {
1503 0 : *pURL = rURL.GetURL();
1504 0 : if( rURL.IsServerMap() )
1505 : {
1506 : // append the relative pixel position !!
1507 0 : Point aPt( rPt );
1508 0 : aPt -= pFly->Frm().Pos();
1509 : // without MapMode-Offset, without Offset, o ... !!!!!
1510 : aPt = GetOut()->LogicToPixel(
1511 0 : aPt, MapMode( MAP_TWIP ) );
1512 0 : ((( *pURL += "?" ) += OUString::number( aPt.getX() ))
1513 0 : += "," ) += OUString::number(aPt.getY() );
1514 : }
1515 : }
1516 0 : pRet = pFly->GetFormat();
1517 : }
1518 0 : if ( bSetTargetFrameName )
1519 0 : *pTargetFrameName = rURL.GetTargetFrameName();
1520 0 : if ( bSetDescription )
1521 0 : *pDescription = pFly->GetFormat()->GetName();
1522 : }
1523 : }
1524 1 : pDView->SetHitTolerancePixel( nOld );
1525 1 : return pRet;
1526 : }
1527 :
1528 0 : const Graphic *SwFEShell::GetGrfAtPos( const Point &rPt,
1529 : OUString &rName, bool &rbLink ) const
1530 : {
1531 0 : if( !Imp()->HasDrawView() )
1532 0 : return 0;
1533 :
1534 : SdrObject* pObj;
1535 : SdrPageView* pPV;
1536 0 : SwDrawView *pDView = const_cast<SwDrawView*>(Imp()->GetDrawView());
1537 :
1538 0 : if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPV ) && pObj->ISA(SwVirtFlyDrawObj) )
1539 : {
1540 0 : SwFlyFrm *pFly = static_cast<SwVirtFlyDrawObj*>(pObj)->GetFlyFrm();
1541 0 : if ( pFly->Lower() && pFly->Lower()->IsNoTextFrm() )
1542 : {
1543 0 : SwGrfNode *pNd = static_cast<SwContentFrm*>(pFly->Lower())->GetNode()->GetGrfNode();
1544 0 : if ( pNd )
1545 : {
1546 0 : if ( pNd->IsGrfLink() )
1547 : {
1548 : // halfway ready graphic?
1549 0 : ::sfx2::SvLinkSource* pLnkObj = pNd->GetLink()->GetObj();
1550 0 : if( pLnkObj && pLnkObj->IsPending() )
1551 0 : return 0;
1552 0 : rbLink = true;
1553 : }
1554 :
1555 0 : pNd->GetFileFilterNms( &rName, 0 );
1556 0 : if ( rName.isEmpty() )
1557 0 : rName = pFly->GetFormat()->GetName();
1558 0 : return &pNd->GetGrf(true);
1559 : }
1560 : }
1561 : }
1562 0 : return 0;
1563 : }
1564 :
1565 0 : const SwFrameFormat* SwFEShell::GetFormatFromObj( const Point& rPt, SwRect** pRectToFill ) const
1566 : {
1567 0 : SwFrameFormat* pRet = 0;
1568 :
1569 0 : if( Imp()->HasDrawView() )
1570 : {
1571 : SdrObject* pObj;
1572 : SdrPageView* pPView;
1573 :
1574 0 : SwDrawView *pDView = const_cast<SwDrawView*>(Imp()->GetDrawView());
1575 :
1576 0 : const auto nOld = pDView->GetHitTolerancePixel();
1577 : // tolerance for Drawing-SS
1578 0 : pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
1579 :
1580 0 : if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SdrSearchOptions::PICKMARKABLE ) )
1581 : {
1582 : // first check it:
1583 0 : if ( pObj->ISA(SwVirtFlyDrawObj) )
1584 0 : pRet = static_cast<SwVirtFlyDrawObj*>(pObj)->GetFormat();
1585 0 : else if ( pObj->GetUserCall() ) //not for group objects
1586 0 : pRet = static_cast<SwDrawContact*>(pObj->GetUserCall())->GetFormat();
1587 0 : if(pRet && pRectToFill)
1588 0 : **pRectToFill = pObj->GetCurrentBoundRect();
1589 : }
1590 0 : pDView->SetHitTolerancePixel( nOld );
1591 : }
1592 0 : return pRet;
1593 : }
1594 :
1595 : // returns a format too, if the point is over the text of any fly
1596 0 : const SwFrameFormat* SwFEShell::GetFormatFromAnyObj( const Point& rPt ) const
1597 : {
1598 0 : const SwFrameFormat* pRet = GetFormatFromObj( rPt );
1599 0 : if( !pRet || RES_FLYFRMFMT == pRet->Which() )
1600 : {
1601 0 : SwPosition aPos( *GetCrsr()->GetPoint() );
1602 0 : Point aPt( rPt );
1603 0 : GetLayout()->GetCrsrOfst( &aPos, aPt );
1604 0 : SwContentNode *pNd = aPos.nNode.GetNode().GetContentNode();
1605 0 : SwFrm* pFrm = pNd->getLayoutFrm( GetLayout(), &rPt, 0, false )->FindFlyFrm();
1606 0 : pRet = pFrm ? static_cast<SwLayoutFrm*>(pFrm)->GetFormat() : 0;
1607 : }
1608 0 : return pRet;
1609 : }
1610 :
1611 0 : ObjCntType SwFEShell::GetObjCntType( const SdrObject& rObj ) const
1612 : {
1613 0 : ObjCntType eType = OBJCNT_NONE;
1614 :
1615 : // investigate 'master' drawing object, if method
1616 : // is called for a 'virtual' drawing object.
1617 : const SdrObject* pInvestigatedObj;
1618 0 : if ( rObj.ISA(SwDrawVirtObj) )
1619 : {
1620 0 : const SwDrawVirtObj* pDrawVirtObj = static_cast<const SwDrawVirtObj*>(&rObj);
1621 0 : pInvestigatedObj = &(pDrawVirtObj->GetReferencedObj());
1622 : }
1623 : else
1624 : {
1625 0 : pInvestigatedObj = &rObj;
1626 : }
1627 :
1628 0 : if( FmFormInventor == pInvestigatedObj->GetObjInventor() )
1629 : {
1630 0 : eType = OBJCNT_CONTROL;
1631 : uno::Reference< awt::XControlModel > xModel =
1632 0 : static_cast<const SdrUnoObj&>(*pInvestigatedObj).GetUnoControlModel();
1633 0 : if( xModel.is() )
1634 : {
1635 0 : uno::Any aVal;
1636 0 : OUString sName("ButtonType");
1637 0 : uno::Reference< beans::XPropertySet > xSet(xModel, uno::UNO_QUERY);
1638 :
1639 0 : uno::Reference< beans::XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
1640 0 : if(xInfo->hasPropertyByName( sName ))
1641 : {
1642 0 : beans::Property xProperty = xInfo->getPropertyByName( sName );
1643 0 : aVal = xSet->getPropertyValue( sName );
1644 0 : if( aVal.getValue() && form::FormButtonType_URL == *static_cast<form::FormButtonType const *>(aVal.getValue()) )
1645 0 : eType = OBJCNT_URLBUTTON;
1646 0 : }
1647 0 : }
1648 : }
1649 0 : else if( pInvestigatedObj->ISA(SwVirtFlyDrawObj) )
1650 : {
1651 0 : const SwFlyFrm *pFly = static_cast<const SwVirtFlyDrawObj&>(*pInvestigatedObj).GetFlyFrm();
1652 0 : if ( pFly->Lower() && pFly->Lower()->IsNoTextFrm() )
1653 : {
1654 0 : if ( static_cast<const SwContentFrm*>(pFly->Lower())->GetNode()->GetGrfNode() )
1655 0 : eType = OBJCNT_GRF;
1656 : else
1657 0 : eType = OBJCNT_OLE;
1658 : }
1659 : else
1660 0 : eType = OBJCNT_FLY;
1661 : }
1662 0 : else if ( pInvestigatedObj->ISA( SdrObjGroup ) )
1663 : {
1664 0 : SwDrawContact* pDrawContact( dynamic_cast<SwDrawContact*>(GetUserCall( pInvestigatedObj ) ) );
1665 0 : if ( !pDrawContact )
1666 : {
1667 : OSL_FAIL( "<SwFEShell::GetObjCntType(..)> - missing draw contact object" );
1668 0 : eType = OBJCNT_NONE;
1669 : }
1670 : else
1671 : {
1672 0 : SwFrameFormat* pFrameFormat( pDrawContact->GetFormat() );
1673 0 : if ( !pFrameFormat )
1674 : {
1675 : OSL_FAIL( "<SwFEShell::GetObjCntType(..)> - missing frame format" );
1676 0 : eType = OBJCNT_NONE;
1677 : }
1678 0 : else if ( FLY_AS_CHAR != pFrameFormat->GetAnchor().GetAnchorId() )
1679 : {
1680 0 : eType = OBJCNT_GROUPOBJ;
1681 : }
1682 : }
1683 : }
1684 : else
1685 0 : eType = OBJCNT_SIMPLE;
1686 0 : return eType;
1687 : }
1688 :
1689 0 : ObjCntType SwFEShell::GetObjCntType( const Point &rPt, SdrObject *&rpObj ) const
1690 : {
1691 0 : ObjCntType eType = OBJCNT_NONE;
1692 :
1693 0 : if( Imp()->HasDrawView() )
1694 : {
1695 : SdrObject* pObj;
1696 : SdrPageView* pPView;
1697 :
1698 0 : SwDrawView *pDView = const_cast<SwDrawView*>(Imp()->GetDrawView());
1699 :
1700 0 : const auto nOld = pDView->GetHitTolerancePixel();
1701 : // tolerance for Drawing-SS
1702 0 : pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
1703 :
1704 0 : if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SdrSearchOptions::PICKMARKABLE ) )
1705 0 : eType = GetObjCntType( *(rpObj = pObj) );
1706 :
1707 0 : pDView->SetHitTolerancePixel( nOld );
1708 : }
1709 0 : return eType;
1710 : }
1711 :
1712 2647 : ObjCntType SwFEShell::GetObjCntTypeOfSelection( SdrObject** ppObj ) const
1713 : {
1714 2647 : ObjCntType eType = OBJCNT_NONE;
1715 :
1716 2647 : if( Imp()->HasDrawView() )
1717 : {
1718 2647 : const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1719 2647 : for( size_t i = 0, nE = rMrkList.GetMarkCount(); i < nE; ++i )
1720 : {
1721 0 : SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
1722 0 : if( !pObj )
1723 0 : continue;
1724 0 : ObjCntType eTmp = GetObjCntType( *pObj );
1725 0 : if( !i )
1726 : {
1727 0 : eType = eTmp;
1728 0 : if( ppObj ) *ppObj = pObj;
1729 : }
1730 0 : else if( eTmp != eType )
1731 : {
1732 0 : eType = OBJCNT_DONTCARE;
1733 : // once DontCare, always DontCare!
1734 0 : break;
1735 : }
1736 : }
1737 : }
1738 2647 : return eType;
1739 : }
1740 :
1741 0 : bool SwFEShell::ReplaceSdrObj( const OUString& rGrfName, const OUString& rFltName,
1742 : const Graphic* pGrf )
1743 : {
1744 0 : SET_CURR_SHELL( this );
1745 :
1746 0 : bool bRet = false;
1747 : const SdrMarkList *pMrkList;
1748 0 : if( Imp()->HasDrawView() && 1 ==
1749 0 : ( pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList())->GetMarkCount() )
1750 : {
1751 0 : SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
1752 0 : SwFrameFormat *pFormat = FindFrameFormat( pObj );
1753 :
1754 : // store attributes, then set the graphic
1755 0 : SfxItemSet aFrmSet( mpDoc->GetAttrPool(),
1756 0 : pFormat->GetAttrSet().GetRanges() );
1757 0 : aFrmSet.Set( pFormat->GetAttrSet() );
1758 :
1759 : // set size and position?
1760 0 : if( !pObj->ISA(SwVirtFlyDrawObj) )
1761 : {
1762 : // then let's do it:
1763 0 : const Rectangle &rBound = pObj->GetSnapRect();
1764 0 : Point aRelPos( pObj->GetRelativePos() );
1765 :
1766 0 : const long nWidth = rBound.Right() - rBound.Left();
1767 0 : const long nHeight= rBound.Bottom() - rBound.Top();
1768 : aFrmSet.Put( SwFormatFrmSize( ATT_MIN_SIZE,
1769 0 : std::max( nWidth, long(MINFLY) ),
1770 0 : std::max( nHeight, long(MINFLY) )));
1771 :
1772 0 : if( SfxItemState::SET != aFrmSet.GetItemState( RES_HORI_ORIENT ))
1773 0 : aFrmSet.Put( SwFormatHoriOrient( aRelPos.getX(), text::HoriOrientation::NONE, text::RelOrientation::FRAME ));
1774 :
1775 0 : if( SfxItemState::SET != aFrmSet.GetItemState( RES_VERT_ORIENT ))
1776 0 : aFrmSet.Put( SwFormatVertOrient( aRelPos.getY(), text::VertOrientation::NONE, text::RelOrientation::FRAME ));
1777 :
1778 : }
1779 :
1780 0 : pObj->GetOrdNum();
1781 :
1782 0 : StartAllAction();
1783 0 : StartUndo();
1784 :
1785 : // delete "Sdr-Object", insert the graphic instead
1786 0 : DelSelectedObj();
1787 :
1788 0 : GetDoc()->getIDocumentContentOperations().Insert( *GetCrsr(), rGrfName, rFltName, pGrf, &aFrmSet, NULL, NULL );
1789 :
1790 0 : EndUndo();
1791 0 : EndAllAction();
1792 0 : bRet = true;
1793 : }
1794 0 : return bRet;
1795 : }
1796 :
1797 0 : static sal_uInt16 SwFormatGetPageNum(const SwFlyFrameFormat * pFormat)
1798 : {
1799 : OSL_ENSURE(pFormat != NULL, "invalid argument");
1800 :
1801 0 : SwFlyFrm * pFrm = pFormat->GetFrm();
1802 :
1803 : sal_uInt16 aResult;
1804 :
1805 0 : if (pFrm != NULL)
1806 0 : aResult = pFrm->GetPhyPageNum();
1807 : else
1808 0 : aResult = pFormat->GetAnchor().GetPageNum();
1809 :
1810 0 : return aResult;
1811 : }
1812 :
1813 : #include <fmtcnct.hxx>
1814 :
1815 0 : void SwFEShell::GetConnectableFrameFormats(SwFrameFormat & rFormat,
1816 : const OUString & rReference,
1817 : bool bSuccessors,
1818 : ::std::vector< OUString > & aPrevPageVec,
1819 : ::std::vector< OUString > & aThisPageVec,
1820 : ::std::vector< OUString > & aNextPageVec,
1821 : ::std::vector< OUString > & aRestVec)
1822 : {
1823 0 : StartAction();
1824 :
1825 0 : SwFormatChain rChain = rFormat.GetChain();
1826 0 : SwFrameFormat * pOldChainNext = static_cast<SwFrameFormat *>(rChain.GetNext());
1827 0 : SwFrameFormat * pOldChainPrev = static_cast<SwFrameFormat *>(rChain.GetPrev());
1828 :
1829 0 : if (pOldChainNext)
1830 0 : mpDoc->Unchain(rFormat);
1831 :
1832 0 : if (pOldChainPrev)
1833 0 : mpDoc->Unchain(*pOldChainPrev);
1834 :
1835 0 : const size_t nCnt = mpDoc->GetFlyCount(FLYCNTTYPE_FRM);
1836 :
1837 : /* potential successors resp. predecessors */
1838 0 : ::std::vector< const SwFrameFormat * > aTmpSpzArray;
1839 :
1840 0 : mpDoc->FindFlyByName(rReference);
1841 :
1842 0 : for (size_t n = 0; n < nCnt; ++n)
1843 : {
1844 0 : const SwFrameFormat & rFormat1 = *(mpDoc->GetFlyNum(n, FLYCNTTYPE_FRM));
1845 :
1846 : /*
1847 : pFormat is a potential successor of rFormat if it is chainable after
1848 : rFormat.
1849 :
1850 : pFormat is a potential predecessor of rFormat if rFormat is chainable
1851 : after pFormat.
1852 : */
1853 :
1854 : SwChainRet nChainState;
1855 :
1856 0 : if (bSuccessors)
1857 0 : nChainState = mpDoc->Chainable(rFormat, rFormat1);
1858 : else
1859 0 : nChainState = mpDoc->Chainable(rFormat1, rFormat);
1860 :
1861 0 : if (nChainState == SwChainRet::OK)
1862 : {
1863 0 : aTmpSpzArray.push_back(&rFormat1);
1864 :
1865 : }
1866 :
1867 : }
1868 :
1869 0 : if (aTmpSpzArray.size() > 0)
1870 : {
1871 0 : aPrevPageVec.clear();
1872 0 : aThisPageVec.clear();
1873 0 : aNextPageVec.clear();
1874 0 : aRestVec.clear();
1875 :
1876 : /* number of page rFormat resides on */
1877 0 : sal_uInt16 nPageNum = SwFormatGetPageNum(static_cast<SwFlyFrameFormat *>(&rFormat));
1878 :
1879 0 : ::std::vector< const SwFrameFormat * >::const_iterator aIt;
1880 :
1881 0 : for (aIt = aTmpSpzArray.begin(); aIt != aTmpSpzArray.end(); ++aIt)
1882 : {
1883 0 : const OUString aString = (*aIt)->GetName();
1884 :
1885 : /* rFormat is not a valid successor or predecessor of
1886 : itself */
1887 0 : if (aString != rReference && aString != rFormat.GetName())
1888 : {
1889 : sal_uInt16 nNum1 =
1890 0 : SwFormatGetPageNum(static_cast<const SwFlyFrameFormat *>(*aIt));
1891 :
1892 0 : if (nNum1 == nPageNum -1)
1893 0 : aPrevPageVec.push_back(aString);
1894 0 : else if (nNum1 == nPageNum)
1895 0 : aThisPageVec.push_back(aString);
1896 0 : else if (nNum1 == nPageNum + 1)
1897 0 : aNextPageVec.push_back(aString);
1898 : else
1899 0 : aRestVec.push_back(aString);
1900 : }
1901 0 : }
1902 :
1903 : }
1904 :
1905 0 : if (pOldChainNext)
1906 0 : mpDoc->Chain(rFormat, *pOldChainNext);
1907 :
1908 0 : if (pOldChainPrev)
1909 0 : mpDoc->Chain(*pOldChainPrev, rFormat);
1910 :
1911 0 : EndAction();
1912 0 : }
1913 :
1914 : // #i73249#
1915 0 : OUString SwFEShell::GetObjTitle() const
1916 : {
1917 0 : if ( Imp()->HasDrawView() )
1918 : {
1919 0 : const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
1920 0 : if ( pMrkList->GetMarkCount() == 1 )
1921 : {
1922 0 : const SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
1923 0 : const SwFrameFormat* pFormat = FindFrameFormat( pObj );
1924 0 : if ( pFormat->Which() == RES_FLYFRMFMT )
1925 : {
1926 0 : return static_cast<const SwFlyFrameFormat*>(pFormat)->GetObjTitle();
1927 : }
1928 0 : return pObj->GetTitle();
1929 : }
1930 : }
1931 :
1932 0 : return OUString();
1933 : }
1934 :
1935 0 : void SwFEShell::SetObjTitle( const OUString& rTitle )
1936 : {
1937 0 : if ( Imp()->HasDrawView() )
1938 : {
1939 0 : const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
1940 0 : if ( pMrkList->GetMarkCount() == 1 )
1941 : {
1942 0 : SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
1943 0 : SwFrameFormat* pFormat = FindFrameFormat( pObj );
1944 0 : if ( pFormat->Which() == RES_FLYFRMFMT )
1945 : {
1946 0 : GetDoc()->SetFlyFrmTitle( dynamic_cast<SwFlyFrameFormat&>(*pFormat),
1947 0 : rTitle );
1948 : }
1949 : else
1950 : {
1951 0 : pObj->SetTitle( rTitle );
1952 : }
1953 : }
1954 : }
1955 0 : }
1956 :
1957 0 : OUString SwFEShell::GetObjDescription() const
1958 : {
1959 0 : if ( Imp()->HasDrawView() )
1960 : {
1961 0 : const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
1962 0 : if ( pMrkList->GetMarkCount() == 1 )
1963 : {
1964 0 : const SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
1965 0 : const SwFrameFormat* pFormat = FindFrameFormat( pObj );
1966 0 : if ( pFormat->Which() == RES_FLYFRMFMT )
1967 : {
1968 0 : return dynamic_cast<const SwFlyFrameFormat&>(*pFormat).GetObjDescription();
1969 : }
1970 0 : return pObj->GetDescription();
1971 : }
1972 : }
1973 :
1974 0 : return OUString();
1975 : }
1976 :
1977 0 : void SwFEShell::SetObjDescription( const OUString& rDescription )
1978 : {
1979 0 : if ( Imp()->HasDrawView() )
1980 : {
1981 0 : const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
1982 0 : if ( pMrkList->GetMarkCount() == 1 )
1983 : {
1984 0 : SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
1985 0 : SwFrameFormat* pFormat = FindFrameFormat( pObj );
1986 0 : if ( pFormat->Which() == RES_FLYFRMFMT )
1987 : {
1988 0 : GetDoc()->SetFlyFrmDescription(dynamic_cast<SwFlyFrameFormat&>(*pFormat),
1989 0 : rDescription);
1990 : }
1991 : else
1992 : {
1993 0 : pObj->SetDescription( rDescription );
1994 : }
1995 : }
1996 : }
1997 0 : }
1998 :
1999 0 : void SwFEShell::AlignFormulaToBaseline( const uno::Reference < embed::XEmbeddedObject >& xObj, SwFlyFrm * pFly )
2000 : {
2001 : #if OSL_DEBUG_LEVEL > 0
2002 : SvGlobalName aCLSID( xObj->getClassID() );
2003 : const bool bStarMath = ( SotExchange::IsMath( aCLSID ) != 0 );
2004 : OSL_ENSURE( bStarMath, "AlignFormulaToBaseline should only be called for Math objects" );
2005 :
2006 : if ( !bStarMath )
2007 : return;
2008 : #endif
2009 :
2010 0 : if (!pFly)
2011 0 : pFly = FindFlyFrm( xObj );
2012 : OSL_ENSURE( pFly , "No fly frame!" );
2013 0 : SwFrameFormat * pFrameFormat = pFly ? pFly->GetFormat() : 0;
2014 :
2015 : // baseline to baseline alignment should only be applied to formulas anchored as char
2016 0 : if ( pFly && pFrameFormat && FLY_AS_CHAR == pFrameFormat->GetAnchor().GetAnchorId() )
2017 : {
2018 : // get baseline from Math object
2019 0 : uno::Any aBaseline;
2020 0 : if( svt::EmbeddedObjectRef::TryRunningState( xObj ) )
2021 : {
2022 0 : uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
2023 0 : if ( xSet.is() )
2024 : {
2025 : try
2026 : {
2027 0 : aBaseline = xSet->getPropertyValue("BaseLine");
2028 : }
2029 0 : catch ( uno::Exception& )
2030 : {
2031 : OSL_FAIL( "Baseline could not be retrieved from Starmath!" );
2032 : }
2033 0 : }
2034 : }
2035 :
2036 0 : sal_Int32 nBaseline = ::comphelper::getINT32(aBaseline);
2037 0 : const MapMode aSourceMapMode( MAP_100TH_MM );
2038 0 : const MapMode aTargetMapMode( MAP_TWIP );
2039 0 : nBaseline = OutputDevice::LogicToLogic( nBaseline, aSourceMapMode.GetMapUnit(), aTargetMapMode.GetMapUnit() );
2040 :
2041 : OSL_ENSURE( nBaseline > 0, "Wrong value of Baseline while retrieving from Starmath!" );
2042 : //nBaseline must be moved by aPrt position
2043 0 : const SwFlyFrameFormat *pFlyFrameFormat = pFly->GetFormat();
2044 : OSL_ENSURE( pFlyFrameFormat, "fly frame format missing!" );
2045 0 : if ( pFlyFrameFormat )
2046 0 : nBaseline += pFlyFrameFormat->GetLastFlyFrmPrtRectPos().Y();
2047 :
2048 0 : const SwFormatVertOrient &rVert = pFrameFormat->GetVertOrient();
2049 0 : SwFormatVertOrient aVert( rVert );
2050 0 : aVert.SetPos( -nBaseline );
2051 0 : aVert.SetVertOrient( com::sun::star::text::VertOrientation::NONE );
2052 :
2053 0 : pFrameFormat->LockModify();
2054 0 : pFrameFormat->SetFormatAttr( aVert );
2055 0 : pFrameFormat->UnlockModify();
2056 0 : pFly->InvalidatePos();
2057 : }
2058 0 : }
2059 :
2060 0 : void SwFEShell::AlignAllFormulasToBaseline()
2061 : {
2062 0 : StartAllAction();
2063 :
2064 : SwStartNode *pStNd;
2065 0 : SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
2066 0 : while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
2067 : {
2068 0 : ++aIdx;
2069 0 : SwOLENode *pOleNode = dynamic_cast< SwOLENode * >( &aIdx.GetNode() );
2070 0 : if ( pOleNode )
2071 : {
2072 0 : const uno::Reference < embed::XEmbeddedObject > & xObj( pOleNode->GetOLEObj().GetOleRef() );
2073 0 : if (xObj.is())
2074 : {
2075 0 : SvGlobalName aCLSID( xObj->getClassID() );
2076 0 : if ( SotExchange::IsMath( aCLSID ) )
2077 0 : AlignFormulaToBaseline( xObj );
2078 0 : }
2079 : }
2080 :
2081 0 : aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
2082 : }
2083 :
2084 0 : EndAllAction();
2085 177 : }
2086 :
2087 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|