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, SwFmtAnchor& 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 SwCntntNode *pCntNd = rNode.GetCntntNode();
92 0 : const SwCntntFrm* 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 20 : static bool lcl_FindAnchorPos(
102 : SwEditShell& rEditShell,
103 : SwDoc& rDoc,
104 : const Point& rPt,
105 : const SwFrm& rFrm,
106 : SfxItemSet& rSet )
107 : {
108 20 : bool bRet = true;
109 20 : SwFmtAnchor aNewAnch( (SwFmtAnchor&)rSet.Get( RES_ANCHOR ) );
110 20 : RndStdIds nNew = aNewAnch.GetAnchorId();
111 : const SwFrm *pNewAnch;
112 :
113 : //determine new anchor
114 20 : Point aTmpPnt( rPt );
115 20 : switch( nNew )
116 : {
117 : case FLY_AS_CHAR: // also include this?
118 : case FLY_AT_PARA:
119 : case FLY_AT_CHAR: // LAYER_IMPL
120 : {
121 : // starting from the upper-left corner of the Fly,
122 : // search nearest CntntFrm
123 20 : const SwFrm* pFrm = rFrm.IsFlyFrm() ? ((SwFlyFrm&)rFrm).GetAnchorFrm()
124 20 : : &rFrm;
125 10 : pNewAnch = ::FindAnchor( pFrm, aTmpPnt );
126 10 : if( pNewAnch->IsProtected() )
127 : {
128 0 : bRet = false;
129 0 : break;
130 : }
131 :
132 10 : SwPosition aPos( *((SwCntntFrm*)pNewAnch)->GetNode() );
133 10 : if ((FLY_AT_CHAR == nNew) || (FLY_AS_CHAR == nNew))
134 : {
135 : // textnode should be found, as only in those
136 : // a content bound frame can be anchored
137 6 : SwCrsrMoveState aState( MV_SETONLYTEXT );
138 6 : aTmpPnt.setX(aTmpPnt.getX() - 1); // do not land in the fly!
139 6 : if( !pNewAnch->GetCrsrOfst( &aPos, aTmpPnt, &aState ) )
140 : {
141 0 : SwCntntNode* pCNd = ((SwCntntFrm*)pNewAnch)->GetNode();
142 0 : if( pNewAnch->Frm().Bottom() < aTmpPnt.Y() )
143 0 : pCNd->MakeStartIndex( &aPos.nContent );
144 : else
145 0 : pCNd->MakeEndIndex( &aPos.nContent );
146 : }
147 : else
148 : {
149 6 : if ( rEditShell.PosInsideInputFld( aPos ) )
150 : {
151 0 : aPos.nContent = rEditShell.StartOfInputFldAtPos( aPos );
152 : }
153 : }
154 : }
155 10 : aNewAnch.SetAnchor( &aPos );
156 : }
157 10 : break;
158 :
159 : case FLY_AT_FLY: // LAYER_IMPL
160 : {
161 : // starting from the upper-left corner of the Fly
162 : // search nearest SwFlyFrm
163 0 : SwCrsrMoveState aState( MV_SETONLYTEXT );
164 0 : SwPosition aPos( rDoc.GetNodes() );
165 0 : aTmpPnt.setX(aTmpPnt.getX() - 1); // do not land in the fly!
166 0 : rDoc.getIDocumentLayoutAccess().GetCurrentLayout()->GetCrsrOfst( &aPos, aTmpPnt, &aState );
167 : pNewAnch = ::FindAnchor(
168 0 : aPos.nNode.GetNode().GetCntntNode()->getLayoutFrm( rFrm.getRootFrm(), 0, 0, false ),
169 0 : aTmpPnt )->FindFlyFrm();
170 :
171 0 : if( pNewAnch && &rFrm != pNewAnch && !pNewAnch->IsProtected() )
172 : {
173 0 : aPos.nNode = *((SwFlyFrm*)pNewAnch)->GetFmt()->GetCntnt().
174 0 : GetCntntIdx();
175 0 : aNewAnch.SetAnchor( &aPos );
176 0 : break;
177 0 : }
178 : }
179 :
180 0 : aNewAnch.SetType( nNew = FLY_AT_PAGE );
181 : // no break
182 :
183 : case FLY_AT_PAGE:
184 10 : pNewAnch = rFrm.FindPageFrm();
185 10 : aNewAnch.SetPageNum( pNewAnch->GetPhyPageNum() );
186 10 : break;
187 :
188 : default:
189 : OSL_ENSURE( false, "Falsche ID fuer neuen Anker." );
190 : }
191 :
192 20 : rSet.Put( aNewAnch );
193 20 : return bRet;
194 : }
195 :
196 : //! also used in unoframe.cxx
197 :
198 24 : bool sw_ChkAndSetNewAnchor(
199 : SwEditShell& rEditShell,
200 : const SwFlyFrm& rFly,
201 : SfxItemSet& rSet )
202 : {
203 24 : const SwFrmFmt& rFmt = *rFly.GetFmt();
204 24 : const SwFmtAnchor &rOldAnch = rFmt.GetAnchor();
205 24 : const RndStdIds nOld = rOldAnch.GetAnchorId();
206 :
207 24 : RndStdIds nNew = ((SwFmtAnchor&)rSet.Get( RES_ANCHOR )).GetAnchorId();
208 :
209 24 : if( nOld == nNew )
210 4 : return false;
211 :
212 20 : SwDoc* pDoc = (SwDoc*)rFmt.GetDoc();
213 :
214 : #if OSL_DEBUG_LEVEL > 0
215 : OSL_ENSURE( !(nNew == FLY_AT_PAGE &&
216 : (FLY_AT_PARA==nOld || FLY_AT_CHAR==nOld || FLY_AS_CHAR==nOld ) &&
217 : pDoc->IsInHeaderFooter( rOldAnch.GetCntntAnchor()->nNode )),
218 : "forbidden anchor change in Head/Foot." );
219 : #endif
220 :
221 20 : return ::lcl_FindAnchorPos( rEditShell, *pDoc, rFly.Frm().Pos(), rFly, rSet );
222 : }
223 :
224 0 : void SwFEShell::SelectFlyFrm( SwFlyFrm& rFrm, bool bNew )
225 : {
226 0 : SET_CURR_SHELL( this );
227 :
228 : // The frame is new, thus select it.
229 : // !! Always select the frame, if it's not selected.
230 : // - it could be a new "old" one because the anchor was changed
231 : // - "old" frames have had to be selected previously otherwise they could
232 : // not have been changed
233 : // The frames should not be selected by the document position, because
234 : // it should have been selected!
235 0 : SwViewImp *pImpl = Imp();
236 0 : if( GetWin() && (bNew || !pImpl->GetDrawView()->AreObjectsMarked()) )
237 : {
238 : OSL_ENSURE( rFrm.IsFlyFrm(), "SelectFlyFrm will einen Fly" );
239 :
240 : // nothing to be done if the Fly already was selected
241 0 : if ( FindFlyFrm() == &rFrm )
242 0 : return;
243 :
244 : // assure the anchor is drawn
245 0 : if( rFrm.IsFlyInCntFrm() && rFrm.GetAnchorFrm() )
246 0 : rFrm.GetAnchorFrm()->SetCompletePaint();
247 :
248 0 : if( pImpl->GetDrawView()->AreObjectsMarked() )
249 0 : pImpl->GetDrawView()->UnmarkAll();
250 :
251 0 : pImpl->GetDrawView()->MarkObj( rFrm.GetVirtDrawObj(),
252 0 : pImpl->GetPageView(), false, false );
253 0 : KillPams();
254 0 : ClearMark();
255 0 : SelFlyGrabCrsr();
256 0 : }
257 : }
258 :
259 : // returns a Fly if one is selected
260 2279 : SwFlyFrm *SwFEShell::FindFlyFrm() const
261 : {
262 2279 : if ( Imp()->HasDrawView() )
263 : {
264 : // A Fly is only accessible if it is selected
265 2279 : const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
266 2279 : if( rMrkList.GetMarkCount() != 1 )
267 2279 : return 0;
268 :
269 0 : SdrObject *pO = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
270 0 : return ( pO && pO->ISA(SwVirtFlyDrawObj) ) ? ((SwVirtFlyDrawObj*)pO)->GetFlyFrm() : 0;
271 : }
272 0 : return 0;
273 : }
274 :
275 : // Returns sal_True, if the current Fly could be anchored to another one (so it is inside)
276 0 : const SwFrmFmt* SwFEShell::IsFlyInFly()
277 : {
278 0 : SET_CURR_SHELL( this );
279 :
280 0 : if ( !Imp()->HasDrawView() )
281 0 : return NULL;
282 :
283 0 : const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
284 0 : if ( !rMrkList.GetMarkCount() )
285 : {
286 0 : SwCntntFrm *pCntnt = GetCurrFrm( false );
287 0 : if( !pCntnt )
288 0 : return NULL;
289 0 : SwFlyFrm *pFly = pCntnt->FindFlyFrm();
290 0 : if ( !pFly )
291 0 : return NULL;
292 0 : return pFly->GetFmt();
293 : }
294 0 : else if ( rMrkList.GetMarkCount() != 1 ||
295 0 : !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj()) )
296 0 : return NULL;
297 :
298 0 : SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
299 :
300 0 : SwFrmFmt *pFmt = FindFrmFmt( pObj );
301 0 : if( pFmt && FLY_AT_FLY == pFmt->GetAnchor().GetAnchorId() )
302 : {
303 0 : const SwFrm* pFly = pObj->ISA(SwVirtFlyDrawObj) ?
304 0 : ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetAnchorFrm() :
305 0 : ((SwDrawContact*)GetUserCall(pObj))->GetAnchorFrm( pObj );
306 : OSL_ENSURE( pFly, "IsFlyInFly: Where's my anchor?" );
307 : OSL_ENSURE( pFly->IsFlyFrm(), "IsFlyInFly: Funny anchor!" );
308 0 : return ((SwFlyFrm*)pFly)->GetFmt();
309 : }
310 :
311 0 : Point aTmpPos = pObj->GetCurrentBoundRect().TopLeft();
312 :
313 : SwFrm *pTxtFrm;
314 : {
315 0 : SwCrsrMoveState aState( MV_SETONLYTEXT );
316 0 : SwNodeIndex aSwNodeIndex( GetDoc()->GetNodes() );
317 0 : SwPosition aPos( aSwNodeIndex );
318 0 : Point aPoint( aTmpPos );
319 0 : aPoint.setX(aPoint.getX() - 1); //do not land in the fly!!
320 0 : GetLayout()->GetCrsrOfst( &aPos, aPoint, &aState );
321 : // determine text frame by left-top-corner of object
322 0 : SwCntntNode *pNd = aPos.nNode.GetNode().GetCntntNode();
323 0 : pTxtFrm = pNd ? pNd->getLayoutFrm(GetLayout(), &aTmpPos, 0, false) : NULL;
324 : }
325 0 : const SwFrm *pTmp = pTxtFrm ? ::FindAnchor(pTxtFrm, aTmpPos) : NULL;
326 0 : const SwFlyFrm *pFly = pTmp ? pTmp->FindFlyFrm() : NULL;
327 0 : if( pFly )
328 0 : return pFly->GetFmt();
329 0 : return NULL;
330 : }
331 :
332 0 : void SwFEShell::SetFlyPos( const Point& rAbsPos )
333 : {
334 0 : SET_CURR_SHELL( this );
335 :
336 : // Determine reference point in document coordinates
337 0 : SwCntntFrm *pCntnt = GetCurrFrm( false );
338 0 : if( !pCntnt )
339 0 : return;
340 0 : SwFlyFrm *pFly = pCntnt->FindFlyFrm();
341 0 : if ( !pFly )
342 0 : return;
343 :
344 : //SwSaveHdl aSaveX( Imp() );
345 :
346 : // Set an anchor starting from the absolute position for paragraph bound Flys
347 : // Anchor and new RelPos will be calculated and set by the Fly
348 0 : if ( pFly->IsFlyAtCntFrm() )
349 0 : ((SwFlyAtCntFrm*)pFly)->SetAbsPos( rAbsPos );
350 : else
351 : {
352 0 : const SwFrm *pAnch = pFly->GetAnchorFrm();
353 0 : Point aOrient( pAnch->Frm().Pos() );
354 :
355 0 : if ( pFly->IsFlyInCntFrm() )
356 0 : aOrient.setX(rAbsPos.getX());
357 :
358 : // calculate RelPos.
359 0 : aOrient.setX(rAbsPos.getX() - aOrient.getX());
360 0 : aOrient.setY(rAbsPos.getY() - aOrient.getY());
361 0 : pFly->ChgRelPos( aOrient );
362 : }
363 0 : CallChgLnk(); // call the AttrChangeNotify on the UI-side.
364 : }
365 :
366 0 : Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt )
367 : {
368 0 : Point aRet;
369 :
370 0 : SET_CURR_SHELL( this );
371 :
372 0 : if ( !Imp()->HasDrawView() )
373 0 : return aRet;
374 :
375 0 : const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
376 0 : if ( rMrkList.GetMarkCount() != 1 ||
377 0 : !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj()) )
378 0 : return aRet;
379 :
380 0 : SdrObject* pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
381 : // #i28701#
382 0 : SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj );
383 0 : SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
384 0 : const RndStdIds nAnchorId = rFmt.GetAnchor().GetAnchorId();
385 :
386 0 : if ( FLY_AS_CHAR == nAnchorId )
387 0 : return aRet;
388 :
389 0 : bool bFlyFrame = pObj->ISA(SwVirtFlyDrawObj);
390 :
391 0 : SwFlyFrm* pFly = 0L;
392 : const SwFrm* pOldAnch;
393 0 : const SwFrm* pFooterOrHeader = NULL;
394 :
395 0 : if( bFlyFrame )
396 : {
397 : // Calculate reference point in document coordinates
398 0 : SwCntntFrm *pCntnt = GetCurrFrm( false );
399 0 : if( !pCntnt )
400 0 : return aRet;
401 0 : pFly = pCntnt->FindFlyFrm();
402 0 : if ( !pFly )
403 0 : return aRet;
404 0 : pOldAnch = pFly->GetAnchorFrm();
405 0 : if( !pOldAnch )
406 0 : return aRet;
407 0 : if ( FLY_AT_PAGE != nAnchorId )
408 : {
409 0 : pFooterOrHeader = pCntnt->FindFooterOrHeader();
410 : }
411 : }
412 : // set <pFooterOrHeader> also for drawing
413 : // objects, but not for control objects.
414 : // Necessary for moving 'anchor symbol' at the user interface inside header/footer.
415 0 : else if ( !::CheckControlLayer( pObj ) )
416 : {
417 0 : SwCntntFrm *pCntnt = GetCurrFrm( false );
418 0 : if( !pCntnt )
419 0 : return aRet;
420 0 : pFooterOrHeader = pCntnt->FindFooterOrHeader();
421 : }
422 :
423 : // Search nearest SwFlyFrm starting from the upper-left corner
424 : // of the fly
425 0 : SwCntntFrm *pTxtFrm = NULL;
426 : {
427 0 : SwCrsrMoveState aState( MV_SETONLYTEXT );
428 0 : SwPosition aPos( GetDoc()->GetNodes().GetEndOfExtras() );
429 0 : Point aTmpPnt( rAbsPos );
430 0 : GetLayout()->GetCrsrOfst( &aPos, aTmpPnt, &aState );
431 0 : if ( nAnchorId != FLY_AT_CHAR
432 0 : || !PosInsideInputFld( aPos ) )
433 : {
434 0 : pTxtFrm = aPos.nNode.GetNode().GetCntntNode()->getLayoutFrm( GetLayout(), 0, &aPos, false );
435 0 : }
436 : }
437 0 : const SwFrm *pNewAnch = NULL;
438 0 : if( pTxtFrm != NULL )
439 : {
440 0 : if ( FLY_AT_PAGE == nAnchorId )
441 : {
442 0 : pNewAnch = pTxtFrm->FindPageFrm();
443 : }
444 : else
445 : {
446 0 : pNewAnch = ::FindAnchor( pTxtFrm, rAbsPos );
447 :
448 0 : if( FLY_AT_FLY == nAnchorId ) // LAYER_IMPL
449 : {
450 0 : pNewAnch = pNewAnch->FindFlyFrm();
451 : }
452 : }
453 : }
454 :
455 0 : if( pNewAnch && !pNewAnch->IsProtected() )
456 : {
457 0 : const SwFlyFrm* pCheck = bFlyFrame ? pNewAnch->FindFlyFrm() : 0;
458 : // If we land inside the frame, make sure
459 : // that the frame does not land inside its own content
460 0 : while( pCheck )
461 : {
462 0 : if( pCheck == pFly )
463 0 : break;
464 0 : const SwFrm *pTmp = pCheck->GetAnchorFrm();
465 0 : pCheck = pTmp ? pTmp->FindFlyFrm() : NULL;
466 : }
467 :
468 : // Do not switch from header/footer to another area,
469 : // do not switch to a header/footer
470 0 : if( !pCheck &&
471 0 : pFooterOrHeader == pNewAnch->FindFooterOrHeader() )
472 : {
473 0 : aRet = pNewAnch->GetFrmAnchorPos( ::HasWrap( pObj ) );
474 :
475 0 : if ( bMoveIt || (nAnchorId == FLY_AT_CHAR) )
476 : {
477 0 : SwFmtAnchor aAnch( rFmt.GetAnchor() );
478 0 : switch ( nAnchorId )
479 : {
480 : case FLY_AT_PARA:
481 : {
482 0 : SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
483 0 : pPos->nNode = *pTxtFrm->GetNode();
484 0 : pPos->nContent.Assign(0,0);
485 0 : break;
486 : }
487 : case FLY_AT_PAGE:
488 : {
489 : aAnch.SetPageNum( ((const SwPageFrm*)pNewAnch)->
490 0 : GetPhyPageNum() );
491 0 : break;
492 : }
493 :
494 : case FLY_AT_FLY:
495 : {
496 0 : SwPosition aPos( *((SwFlyFrm*)pNewAnch)->GetFmt()->
497 0 : GetCntnt().GetCntntIdx() );
498 0 : aAnch.SetAnchor( &aPos );
499 0 : break;
500 : }
501 :
502 : case FLY_AT_CHAR:
503 : {
504 0 : SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
505 0 : Point aTmpPnt( rAbsPos );
506 0 : if( pTxtFrm->GetCrsrOfst( pPos, aTmpPnt, NULL ) )
507 : {
508 0 : SwRect aTmpRect;
509 0 : pTxtFrm->GetCharRect( aTmpRect, *pPos );
510 0 : aRet = aTmpRect.Pos();
511 : }
512 : else
513 : {
514 0 : pPos->nNode = *pTxtFrm->GetNode();
515 0 : pPos->nContent.Assign(0,0);
516 : }
517 0 : break;
518 : }
519 : default:
520 0 : break;
521 :
522 : }
523 :
524 0 : if( bMoveIt )
525 : {
526 0 : StartAllAction();
527 : // --> handle change of anchor node:
528 : // if count of the anchor frame also change, the fly frames have to be
529 : // re-created. Thus, delete all fly frames except the <this> before the
530 : // anchor attribute is change and re-create them afterwards.
531 : {
532 0 : SwHandleAnchorNodeChg* pHandleAnchorNodeChg( 0L );
533 0 : SwFlyFrmFmt* pFlyFrmFmt( dynamic_cast<SwFlyFrmFmt*>(&rFmt) );
534 0 : if ( pFlyFrmFmt )
535 : {
536 : pHandleAnchorNodeChg =
537 0 : new SwHandleAnchorNodeChg( *pFlyFrmFmt, aAnch );
538 : }
539 0 : rFmt.GetDoc()->SetAttr( aAnch, rFmt );
540 0 : delete pHandleAnchorNodeChg;
541 : }
542 : // #i28701# - no call of method
543 : // <CheckCharRectAndTopOfLine()> for to-character anchored
544 : // Writer fly frame needed. This method call can cause a
545 : // format of the anchor frame, which is no longer intended.
546 : // Instead clear the anchor character rectangle and
547 : // the top of line values for all to-character anchored objects.
548 0 : pAnchoredObj->ClearCharRectAndTopOfLine();
549 0 : EndAllAction();
550 0 : }
551 : }
552 :
553 0 : SwRect aTmpRect( aRet, rAbsPos );
554 0 : if( aTmpRect.HasArea() )
555 0 : MakeVisible( aTmpRect );
556 : #if OSL_DEBUG_LEVEL > 0
557 : //TODO: That doesn't seem to be intended
558 : if( Color(COL_TRANSPARENT) != GetOut()->GetLineColor() )
559 : {
560 : OSL_FAIL( "Hey, Joe: Where's my Null Pen?" );
561 : GetOut()->SetLineColor( Color(COL_TRANSPARENT) );
562 : }
563 : #endif
564 : }
565 : }
566 :
567 0 : return aRet;
568 : }
569 :
570 0 : const SwFrmFmt *SwFEShell::NewFlyFrm( const SfxItemSet& rSet, bool bAnchValid,
571 : SwFrmFmt *pParent )
572 : {
573 0 : SET_CURR_SHELL( this );
574 0 : StartAllAction();
575 :
576 0 : SwPaM* pCrsr = GetCrsr();
577 0 : const Point aPt( GetCrsrDocPos() );
578 :
579 0 : SwSelBoxes aBoxes;
580 0 : bool bMoveCntnt = true;
581 0 : if( IsTableMode() )
582 : {
583 0 : GetTblSel( *this, aBoxes );
584 0 : if( !aBoxes.empty() )
585 : {
586 : // Crsr should be removed from the removal area.
587 : // Always put it after/on the table; via the
588 : // document position they will be set to the old
589 : // position
590 0 : ParkCrsr( SwNodeIndex( *aBoxes[0]->GetSttNd() ));
591 :
592 : // #i127787# pCurCrsr will be deleted in ParkCrsr,
593 : // we better get the current pCurCrsr instead of working with the
594 : // deleted one:
595 0 : pCrsr = GetCrsr();
596 : }
597 : else
598 0 : bMoveCntnt = false;
599 : }
600 0 : else if( !pCrsr->HasMark() && pCrsr->GetNext() == pCrsr )
601 0 : bMoveCntnt = false;
602 :
603 0 : const SwPosition& rPos = *pCrsr->Start();
604 :
605 0 : SwFmtAnchor& rAnch = (SwFmtAnchor&)rSet.Get( RES_ANCHOR );
606 0 : RndStdIds eRndId = rAnch.GetAnchorId();
607 0 : switch( eRndId )
608 : {
609 : case FLY_AT_PAGE:
610 0 : if( !rAnch.GetPageNum() ) //HotFix: Bug in UpdateByExample
611 0 : rAnch.SetPageNum( 1 );
612 0 : break;
613 :
614 : case FLY_AT_FLY:
615 : case FLY_AT_PARA:
616 : case FLY_AT_CHAR:
617 : case FLY_AS_CHAR:
618 0 : if( !bAnchValid )
619 : {
620 0 : if( FLY_AT_FLY != eRndId )
621 : {
622 0 : rAnch.SetAnchor( &rPos );
623 : }
624 0 : else if( lcl_SetNewFlyPos( rPos.nNode.GetNode(), rAnch, aPt ) )
625 : {
626 0 : eRndId = FLY_AT_PAGE;
627 : }
628 : }
629 0 : break;
630 :
631 : default:
632 : OSL_ENSURE( false, "What is the purpose of this Fly?" );
633 0 : break;
634 : }
635 :
636 : SwFlyFrmFmt *pRet;
637 0 : if( bMoveCntnt )
638 : {
639 0 : GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_INSLAYFMT, NULL );
640 0 : SwFmtAnchor* pOldAnchor = 0;
641 0 : bool bHOriChgd = false, bVOriChgd = false;
642 0 : SwFmtVertOrient aOldV;
643 0 : SwFmtHoriOrient aOldH;
644 :
645 0 : if ( FLY_AT_PAGE != eRndId )
646 : {
647 : // First as with page link. Paragraph/character link on if
648 : // everything was shifted. Then the position is valid!
649 : // JP 13.05.98: if necessary also convert the horizontal/vertical
650 : // orientation, to prevent correction during re-anchoring
651 0 : pOldAnchor = new SwFmtAnchor( rAnch );
652 0 : const_cast<SfxItemSet&>(rSet).Put( SwFmtAnchor( FLY_AT_PAGE, 1 ) );
653 :
654 : const SfxPoolItem* pItem;
655 0 : if( SfxItemState::SET == rSet.GetItemState( RES_HORI_ORIENT, false, &pItem )
656 0 : && text::HoriOrientation::NONE == ((SwFmtHoriOrient*)pItem)->GetHoriOrient() )
657 : {
658 0 : bHOriChgd = true;
659 0 : aOldH = *((SwFmtHoriOrient*)pItem);
660 0 : ((SfxItemSet&)rSet).Put( SwFmtHoriOrient( 0, text::HoriOrientation::LEFT ) );
661 : }
662 0 : if( SfxItemState::SET == rSet.GetItemState( RES_VERT_ORIENT, false, &pItem )
663 0 : && text::VertOrientation::NONE == ((SwFmtVertOrient*)pItem)->GetVertOrient() )
664 : {
665 0 : bVOriChgd = true;
666 0 : aOldV = *((SwFmtVertOrient*)pItem);
667 0 : ((SfxItemSet&)rSet).Put( SwFmtVertOrient( 0, text::VertOrientation::TOP ) );
668 : }
669 : }
670 :
671 0 : pRet = GetDoc()->MakeFlyAndMove( *pCrsr, rSet, &aBoxes, pParent );
672 :
673 0 : KillPams();
674 :
675 0 : if( pOldAnchor )
676 : {
677 0 : if( pRet )
678 : {
679 : // calculate new position
680 : // JP 24.03.97: also go via page links
681 : // chaos::anchor should not lie in the shifted area
682 0 : pRet->DelFrms();
683 :
684 0 : const SwFrm* pAnch = ::FindAnchor( GetLayout(), aPt, false );
685 0 : SwPosition aPos( *((SwCntntFrm*)pAnch)->GetNode() );
686 0 : if ( FLY_AS_CHAR == eRndId )
687 : {
688 0 : aPos.nContent.Assign( ((SwCntntFrm*)pAnch)->GetNode(), 0 );
689 : }
690 0 : pOldAnchor->SetAnchor( &aPos );
691 :
692 : // shifting of table selection is not Undo-capable. therefore
693 : // changing the anchors should not be recorded
694 : bool const bDoesUndo =
695 0 : GetDoc()->GetIDocumentUndoRedo().DoesUndo();
696 0 : SwUndoId nLastUndoId(UNDO_EMPTY);
697 0 : if (bDoesUndo &&
698 0 : GetDoc()->GetIDocumentUndoRedo().GetLastUndoInfo(0,
699 0 : & nLastUndoId))
700 : {
701 0 : if (UNDO_INSLAYFMT == nLastUndoId)
702 : {
703 0 : GetDoc()->GetIDocumentUndoRedo().DoUndo(false);
704 : }
705 : }
706 :
707 0 : ((SfxItemSet&)rSet).Put( *pOldAnchor );
708 :
709 0 : if( bHOriChgd )
710 0 : ((SfxItemSet&)rSet).Put( aOldH );
711 0 : if( bVOriChgd )
712 0 : ((SfxItemSet&)rSet).Put( aOldV );
713 :
714 0 : GetDoc()->SetFlyFrmAttr( *pRet, (SfxItemSet&)rSet );
715 0 : GetDoc()->GetIDocumentUndoRedo().DoUndo(bDoesUndo);
716 : }
717 0 : delete pOldAnchor;
718 : }
719 0 : GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_INSLAYFMT, NULL );
720 : }
721 : else
722 : /* If called from a shell try to propagate an
723 : existing adjust item from rPos to the content node of the
724 : new frame. */
725 0 : pRet = GetDoc()->MakeFlySection( eRndId, &rPos, &rSet, pParent, true );
726 :
727 0 : if( pRet )
728 : {
729 0 : SwFlyFrm* pFrm = pRet->GetFrm( &aPt );
730 0 : if( pFrm )
731 0 : SelectFlyFrm( *pFrm, true );
732 : else
733 : {
734 0 : GetLayout()->SetAssertFlyPages();
735 0 : pRet = 0;
736 : }
737 : }
738 0 : EndAllActionAndCall();
739 :
740 0 : return pRet;
741 : }
742 :
743 0 : void SwFEShell::Insert( const OUString& rGrfName, const OUString& rFltName,
744 : const Graphic* pGraphic,
745 : const SfxItemSet* pFlyAttrSet,
746 : const SfxItemSet* pGrfAttrSet,
747 : SwFrmFmt* pFrmFmt )
748 : {
749 0 : SwFlyFrmFmt* pFmt = 0;
750 0 : SET_CURR_SHELL( this );
751 0 : StartAllAction();
752 0 : SwShellCrsr *pStartCursor = dynamic_cast<SwShellCrsr*>(this->GetSwCrsr());
753 0 : SwShellCrsr *pCursor = pStartCursor;
754 0 : do
755 : {
756 0 : if (!pCursor)
757 0 : break;
758 :
759 : // Has the anchor not been set or been set incompletely?
760 0 : if( pFlyAttrSet )
761 : {
762 : const SfxPoolItem* pItem;
763 0 : if( SfxItemState::SET == pFlyAttrSet->GetItemState( RES_ANCHOR, false,
764 0 : &pItem ) )
765 : {
766 0 : SwFmtAnchor* pAnchor = (SwFmtAnchor*)pItem;
767 0 : switch( pAnchor->GetAnchorId())
768 : {
769 : case FLY_AT_PARA:
770 : case FLY_AT_CHAR: // LAYER_IMPL
771 : case FLY_AS_CHAR:
772 0 : if( !pAnchor->GetCntntAnchor() )
773 : {
774 0 : pAnchor->SetAnchor( pCursor->GetPoint() );
775 : }
776 0 : break;
777 : case FLY_AT_FLY:
778 0 : if( !pAnchor->GetCntntAnchor() )
779 : {
780 0 : lcl_SetNewFlyPos( pCursor->GetNode(),
781 0 : *pAnchor, GetCrsrDocPos() );
782 : }
783 0 : break;
784 : case FLY_AT_PAGE:
785 0 : if( !pAnchor->GetPageNum() )
786 : {
787 : pAnchor->SetPageNum( pCursor->GetPageNum(
788 0 : true, &pCursor->GetPtPos() ) );
789 : }
790 0 : break;
791 : default :
792 0 : break;
793 : }
794 : }
795 : }
796 0 : pFmt = GetDoc()->getIDocumentContentOperations().Insert(*pCursor, rGrfName,
797 : rFltName, pGraphic,
798 : pFlyAttrSet,
799 0 : pGrfAttrSet, pFrmFmt );
800 : OSL_ENSURE( pFmt, "Doc->getIDocumentContentOperations().Insert(notxt) failed." );
801 :
802 0 : pCursor = dynamic_cast<SwShellCrsr*>(pCursor->GetNext());
803 : } while( pCursor != pStartCursor );
804 :
805 0 : EndAllAction();
806 :
807 0 : if( pFmt )
808 : {
809 0 : const Point aPt( GetCrsrDocPos() );
810 0 : SwFlyFrm* pFrm = pFmt->GetFrm( &aPt );
811 :
812 0 : if( pFrm )
813 : {
814 : // fdo#36681: Invalidate the content and layout to refresh
815 : // the picture anchoring properly
816 0 : SwPageFrm* pPageFrm = pFrm->FindPageFrmOfAnchor();
817 0 : pPageFrm->InvalidateFlyLayout();
818 0 : pPageFrm->InvalidateCntnt();
819 :
820 0 : SelectFlyFrm( *pFrm, true );
821 : }
822 : else
823 0 : GetLayout()->SetAssertFlyPages();
824 0 : }
825 0 : }
826 :
827 0 : SwFlyFrmFmt* SwFEShell::InsertObject( const svt::EmbeddedObjectRef& xObj,
828 : const SfxItemSet* pFlyAttrSet,
829 : const SfxItemSet* pGrfAttrSet,
830 : SwFrmFmt* pFrmFmt )
831 : {
832 0 : SwFlyFrmFmt* pFmt = 0;
833 0 : SET_CURR_SHELL( this );
834 0 : StartAllAction();
835 0 : FOREACHPAM_START(GetCrsr())
836 0 : pFmt = GetDoc()->getIDocumentContentOperations().Insert(*PCURCRSR, xObj,
837 0 : pFlyAttrSet, pGrfAttrSet, pFrmFmt );
838 : OSL_ENSURE( pFmt, "Doc->getIDocumentContentOperations().Insert(notxt) failed." );
839 :
840 0 : FOREACHPAM_END()
841 0 : EndAllAction();
842 :
843 0 : if( pFmt )
844 : {
845 0 : const Point aPt( GetCrsrDocPos() );
846 0 : SwFlyFrm* pFrm = pFmt->GetFrm( &aPt );
847 :
848 0 : if( pFrm )
849 0 : SelectFlyFrm( *pFrm, true );
850 : else
851 0 : GetLayout()->SetAssertFlyPages();
852 : }
853 :
854 0 : return pFmt;
855 : }
856 :
857 0 : void SwFEShell::InsertDrawObj( SdrObject& rDrawObj,
858 : const Point& rInsertPosition )
859 : {
860 0 : SET_CURR_SHELL( this );
861 :
862 0 : SfxItemSet rFlyAttrSet( GetDoc()->GetAttrPool(), aFrmFmtSetRange );
863 0 : rFlyAttrSet.Put( SwFmtAnchor( FLY_AT_PARA ));
864 : // #i89920#
865 0 : rFlyAttrSet.Put( SwFmtSurround( SURROUND_THROUGHT ) );
866 0 : rDrawObj.SetLayer( getIDocumentDrawModelAccess()->GetHeavenId() );
867 :
868 : // find anchor position
869 0 : SwPaM aPam( mpDoc->GetNodes() );
870 : {
871 0 : SwCrsrMoveState aState( MV_SETONLYTEXT );
872 0 : Point aTmpPt( rInsertPosition );
873 0 : GetLayout()->GetCrsrOfst( aPam.GetPoint(), aTmpPt, &aState );
874 0 : const SwFrm* pFrm = aPam.GetCntntNode()->getLayoutFrm( GetLayout(), 0, 0, false );
875 0 : const Point aRelPos( rInsertPosition.X() - pFrm->Frm().Left(),
876 0 : rInsertPosition.Y() - pFrm->Frm().Top() );
877 0 : rDrawObj.SetRelativePos( aRelPos );
878 0 : ::lcl_FindAnchorPos( *this, *GetDoc(), rInsertPosition, *pFrm, rFlyAttrSet );
879 : }
880 : // insert drawing object into the document creating a new <SwDrawFrmFmt> instance
881 0 : SwDrawFrmFmt* pFmt = GetDoc()->getIDocumentContentOperations().InsertDrawObj( aPam, rDrawObj, rFlyAttrSet );
882 :
883 : // move object to visible layer
884 0 : SwContact* pContact = static_cast<SwContact*>(rDrawObj.GetUserCall());
885 0 : if ( pContact )
886 : {
887 0 : pContact->MoveObjToVisibleLayer( &rDrawObj );
888 : }
889 :
890 0 : if ( pFmt )
891 : {
892 : // select drawing object
893 0 : Imp()->GetDrawView()->MarkObj( &rDrawObj, Imp()->GetPageView(),
894 0 : false, false );
895 : }
896 : else
897 : {
898 0 : GetLayout()->SetAssertFlyPages();
899 0 : }
900 0 : }
901 :
902 0 : void SwFEShell::GetPageObjs( std::vector<SwFrmFmt*>& rFillArr )
903 : {
904 0 : rFillArr.clear();
905 :
906 0 : for( sal_uInt16 n = 0; n < mpDoc->GetSpzFrmFmts()->size(); ++n )
907 : {
908 0 : SwFrmFmt* pFmt = (*mpDoc->GetSpzFrmFmts())[n];
909 0 : if (FLY_AT_PAGE == pFmt->GetAnchor().GetAnchorId())
910 : {
911 0 : rFillArr.push_back( pFmt );
912 : }
913 : }
914 0 : }
915 :
916 0 : void SwFEShell::SetPageObjsNewPage( std::vector<SwFrmFmt*>& rFillArr, int nOffset )
917 : {
918 0 : if( rFillArr.empty() || !nOffset )
919 0 : return;
920 :
921 0 : StartAllAction();
922 0 : StartUndo();
923 :
924 : long nNewPage;
925 0 : SwRootFrm* pTmpRootFrm = GetLayout();
926 0 : sal_uInt16 nMaxPage = pTmpRootFrm->GetPageNum();
927 0 : bool bTmpAssert = false;
928 0 : for( sal_uInt16 n = 0; n < rFillArr.size(); ++n )
929 : {
930 0 : SwFrmFmt* pFmt = rFillArr[n];
931 0 : if( mpDoc->GetSpzFrmFmts()->Contains( pFmt ))
932 : {
933 : // FlyFmt is still valid, therefore process
934 :
935 0 : SwFmtAnchor aNewAnchor( pFmt->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 == pFmt->Which() )
945 : {
946 0 : SwContact *pCon = pFmt->FindContactObj();
947 0 : if( pCon )
948 0 : ((SwDrawContact*)pCon)->DisconnectFromLayout();
949 : }
950 : else
951 0 : pFmt->DelFrms();
952 0 : bTmpAssert = true;
953 : }
954 0 : aNewAnchor.SetPageNum( sal_uInt16(nNewPage) );
955 0 : mpDoc->SetAttr( aNewAnchor, *pFmt );
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( (SwViewShell*)this );
989 :
990 0 : if( !rSet.Set( pFly->GetFmt()->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 : SwFmtAnchor* pAnchor = (SwFmtAnchor*)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->GetFmt()->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( *this, *pFly, rSet );
1043 0 : SwFlyFrmFmt* pFlyFmt = (SwFlyFrmFmt*)pFly->GetFmt();
1044 :
1045 0 : if( GetDoc()->SetFlyFrmAttr( *pFlyFmt, rSet ))
1046 : {
1047 0 : bRet = true;
1048 0 : SwFlyFrm* pFrm = pFlyFmt->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 : SwFrmFmt *pFmt = FindFrmFmt( pObj );
1076 0 : StartAllAction();
1077 0 : if( SfxItemState::SET == rSet.GetItemState( RES_ANCHOR, false ))
1078 : {
1079 0 : RndStdIds nNew = ((SwFmtAnchor&)rSet.Get( RES_ANCHOR )).GetAnchorId();
1080 0 : if ( nNew != pFmt->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( *pFmt, 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->GetFmt()->ResetFmtAttr( nWhich );
1131 0 : pItem = aIter.NextItem();
1132 0 : }
1133 : }
1134 : else
1135 0 : pFly->GetFmt()->ResetFmtAttr( 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 1992 : SwFrmFmt* SwFEShell::GetCurFrmFmt() const
1147 : {
1148 1992 : SwFrmFmt* pRet = 0;
1149 1992 : SwLayoutFrm *pFly = FindFlyFrm();
1150 1992 : if( pFly && ( pRet = (SwFrmFmt*)pFly->GetFmt()->DerivedFrom() ) ==
1151 0 : GetDoc()->GetDfltFrmFmt() )
1152 0 : pRet = 0;
1153 1992 : return pRet;
1154 : }
1155 :
1156 0 : void SwFEShell::SetFrmFmt( SwFrmFmt *pNewFmt, bool bKeepOrient, Point* pDocPos )
1157 : {
1158 0 : SwFlyFrm *pFly = 0;
1159 0 : if(pDocPos)
1160 : {
1161 0 : const SwFrmFmt* pFmt = GetFmtFromObj( *pDocPos );
1162 :
1163 0 : if(PTR_CAST(SwFlyFrmFmt, pFmt))
1164 0 : pFly = ((SwFlyFrmFmt*)pFmt)->GetFrm();
1165 : }
1166 : else
1167 0 : pFly = FindFlyFrm();
1168 : OSL_ENSURE( pFly, "SetFrmFmt: no frame" );
1169 0 : if( pFly )
1170 : {
1171 0 : StartAllAction();
1172 0 : SET_CURR_SHELL( this );
1173 :
1174 0 : SwFlyFrmFmt* pFlyFmt = (SwFlyFrmFmt*)pFly->GetFmt();
1175 0 : const Point aPt( pFly->Frm().Pos() );
1176 :
1177 0 : SfxItemSet* pSet = 0;
1178 : const SfxPoolItem* pItem;
1179 0 : if( SfxItemState::SET == pNewFmt->GetItemState( RES_ANCHOR, false, &pItem ))
1180 : {
1181 0 : pSet = new SfxItemSet( GetDoc()->GetAttrPool(), aFrmFmtSetRange );
1182 0 : pSet->Put( *pItem );
1183 0 : if( !sw_ChkAndSetNewAnchor( *this, *pFly, *pSet ))
1184 0 : delete pSet, pSet = 0;
1185 : }
1186 :
1187 0 : if( GetDoc()->SetFrmFmtToFly( *pFlyFmt, *pNewFmt, pSet, bKeepOrient ))
1188 : {
1189 0 : SwFlyFrm* pFrm = pFlyFmt->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 SwFrmFmt* SwFEShell::GetFlyFrmFmt() 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->GetFmt();
1211 0 : return 0;
1212 : }
1213 :
1214 0 : SwFrmFmt* SwFEShell::GetFlyFrmFmt()
1215 : {
1216 0 : SwFlyFrm* pFly = FindFlyFrm();
1217 0 : if ( !pFly )
1218 : {
1219 0 : SwFrm* pCurrFrm = GetCurrFrm();
1220 0 : pFly = pCurrFrm ? pCurrFrm->FindFlyFrm() : 0;
1221 : }
1222 0 : if( pFly )
1223 0 : return pFly->GetFmt();
1224 0 : return 0;
1225 : }
1226 :
1227 0 : SwRect SwFEShell::GetFlyRect() const
1228 : {
1229 0 : SwCntntFrm *pCntnt = GetCurrFrm( false );
1230 0 : SwFlyFrm *pFly = pCntnt ? pCntnt->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 62 : Size SwFEShell::RequestObjectResize( const SwRect &rRect, const uno::Reference < embed::XEmbeddedObject >& xObj )
1261 : {
1262 62 : Size aResult;
1263 :
1264 62 : SwFlyFrm *pFly = FindFlyFrm( xObj );
1265 62 : if ( !pFly )
1266 : {
1267 0 : aResult = rRect.SSize();
1268 0 : return aResult;
1269 : }
1270 :
1271 62 : aResult = pFly->Prt().SSize();
1272 :
1273 62 : bool bPosProt = pFly->GetFmt()->GetProtect().IsPosProtected();
1274 62 : bool bSizeProt = pFly->GetFmt()->GetProtect().IsSizeProtected();
1275 :
1276 62 : 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 SwNoTxtFrm::Format by calling
1282 : // SwWrtShell::CalcAndSetScale()
1283 62 : if ( rRect.SSize() != pFly->Prt().SSize() && !bSizeProt )
1284 : {
1285 22 : 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 SwTxtNode* pTNd;
1291 : const SwpHints* pHts;
1292 22 : const SwFmtFrmSize& rFrmSz = pFly->GetFmt()->GetFrmSize();
1293 22 : if( bCheckForOLEInCaption &&
1294 0 : 0 != rFrmSz.GetWidthPercent() &&
1295 0 : 0 != (pAnchor = pFly->GetAnchorFrm()) &&
1296 0 : pAnchor->IsTxtFrm() &&
1297 0 : !pAnchor->GetNext() && !pAnchor->GetPrev() &&
1298 0 : pAnchor->GetUpper()->IsFlyFrm() &&
1299 22 : 0 != ( pTNd = ((SwTxtFrm*)pAnchor)->GetNode()->GetTxtNode()) &&
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 == ((SwFmtFld*)pItem)->GetField()->GetTypeId() )
1309 : {
1310 : // sequence field found
1311 0 : SwFlyFrm* pChgFly = (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 : SwFrmFmt *pFmt = pChgFly->GetFmt();
1318 0 : SwFmtFrmSize aFrmSz( pFmt->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 : pFmt->GetDoc()->SetAttr( aFrmSz, *pFmt );
1329 0 : break;
1330 : }
1331 : }
1332 : }
1333 :
1334 : // set the new Size at the fly themself
1335 22 : if ( pFly->Prt().Height() > 0 && pFly->Prt().Width() > 0 )
1336 : {
1337 6 : aSz.Width() += pFly->Frm().Width() - pFly->Prt().Width();
1338 6 : aSz.Height()+= pFly->Frm().Height()- pFly->Prt().Height();
1339 : }
1340 22 : aResult = pFly->ChgSize( aSz );
1341 :
1342 : // if the object changes, the contour is outside the object
1343 : OSL_ENSURE( pFly->Lower()->IsNoTxtFrm(), "Request without NoTxt" );
1344 22 : SwNoTxtNode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetNoTxtNode();
1345 : OSL_ENSURE( pNd, "Request without Node" );
1346 22 : pNd->SetContour( 0 );
1347 22 : ClrContourCache();
1348 : }
1349 :
1350 : // if only the size is to be adjusted, a position is transported with
1351 : // allocated values
1352 62 : Point aPt( pFly->Prt().Pos() );
1353 62 : aPt += pFly->Frm().Pos();
1354 62 : 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 : ((SwFlyAtCntFrm*)pFly)->SetAbsPos( aPt );
1365 : else
1366 : {
1367 0 : const SwFrmFmt *pFmt = pFly->GetFmt();
1368 0 : const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
1369 0 : const SwFmtHoriOrient &rHori = pFmt->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 62 : SwFlyFrmFmt *pFlyFrmFmt = pFly->GetFmt();
1379 : OSL_ENSURE( pFlyFrmFmt, "fly frame format missing!" );
1380 62 : if ( pFlyFrmFmt )
1381 62 : pFlyFrmFmt->SetLastFlyFrmPrtRectPos( pFly->Prt().Pos() ); //stores the value of last Prt rect
1382 :
1383 62 : EndAllAction();
1384 :
1385 62 : return aResult;
1386 : }
1387 :
1388 0 : SwFrmFmt* 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 : SwFrmFmts& rSpzArr = *mpDoc->GetSpzFrmFmts();
1393 0 : sal_uInt16 nCnt = rSpzArr.size();
1394 0 : if( nCnt )
1395 : {
1396 0 : SwNodeIndex& rCrsrNd = GetCrsr()->GetPoint()->nNode;
1397 0 : if( rCrsrNd.GetIndex() > mpDoc->GetNodes().GetEndOfExtras().GetIndex() )
1398 : // Cursor is in the body area!
1399 0 : return 0;
1400 :
1401 0 : for( sal_uInt16 n = 0; n < nCnt; ++n )
1402 : {
1403 0 : SwFrmFmt* pFmt = rSpzArr[ n ];
1404 0 : const SwNodeIndex* pIdx = pFmt->GetCntnt( false ).GetCntntIdx();
1405 : SwStartNode* pSttNd;
1406 0 : if( pIdx &&
1407 0 : 0 != ( pSttNd = pIdx->GetNode().GetStartNode() ) &&
1408 0 : pSttNd->GetIndex() < rCrsrNd.GetIndex() &&
1409 0 : rCrsrNd.GetIndex() < pSttNd->EndOfSectionIndex() )
1410 : {
1411 : // found: return immediately
1412 0 : return pFmt;
1413 : }
1414 : }
1415 : }
1416 0 : return 0;
1417 : }
1418 :
1419 0 : void SwFEShell::SetFlyName( const OUString& rName )
1420 : {
1421 0 : SwLayoutFrm *pFly = FindFlyFrm();
1422 0 : if( pFly )
1423 0 : GetDoc()->SetFlyName( *(SwFlyFrmFmt*)pFly->GetFmt(), rName );
1424 : else {
1425 : OSL_ENSURE( false, "no FlyFrame selected" );
1426 : }
1427 0 : }
1428 :
1429 0 : OUString SwFEShell::GetFlyName() const
1430 : {
1431 0 : SwLayoutFrm *pFly = FindFlyFrm();
1432 0 : if( pFly )
1433 0 : return pFly->GetFmt()->GetName();
1434 :
1435 : OSL_ENSURE( false, "no FlyFrame selected" );
1436 0 : return OUString();
1437 : }
1438 :
1439 0 : const uno::Reference < embed::XEmbeddedObject > SwFEShell::GetOleRef() const
1440 : {
1441 0 : uno::Reference < embed::XEmbeddedObject > xObj;
1442 0 : SwFlyFrm * pFly = FindFlyFrm();
1443 0 : if (pFly && pFly->Lower() && pFly->Lower()->IsNoTxtFrm())
1444 : {
1445 0 : SwOLENode *pNd = ((SwNoTxtFrm*)pFly->Lower())->GetNode()->GetOLENode();
1446 0 : if (pNd)
1447 0 : xObj = pNd->GetOLEObj().GetOleRef();
1448 : }
1449 0 : return xObj;
1450 : }
1451 :
1452 0 : OUString SwFEShell::GetUniqueGrfName() const
1453 : {
1454 0 : return GetDoc()->GetUniqueGrfName();
1455 : }
1456 :
1457 0 : const SwFrmFmt* SwFEShell::IsURLGrfAtPos( const Point& rPt, OUString* pURL,
1458 : OUString *pTargetFrameName,
1459 : OUString *pDescription ) const
1460 : {
1461 0 : if( !Imp()->HasDrawView() )
1462 0 : return 0;
1463 :
1464 : SdrObject* pObj;
1465 : SdrPageView* pPV;
1466 0 : const SwFrmFmt* pRet = 0;
1467 0 : SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
1468 :
1469 0 : sal_uInt16 nOld = pDView->GetHitTolerancePixel();
1470 0 : pDView->SetHitTolerancePixel( 2 );
1471 :
1472 0 : if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPV,SDRSEARCH_PICKMACRO ) &&
1473 0 : pObj->ISA(SwVirtFlyDrawObj) )
1474 : {
1475 0 : SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
1476 0 : const SwFmtURL &rURL = pFly->GetFmt()->GetURL();
1477 0 : if( !rURL.GetURL().isEmpty() || rURL.GetMap() )
1478 : {
1479 0 : bool bSetTargetFrameName = pTargetFrameName != 0;
1480 0 : bool bSetDescription = pDescription != 0;
1481 0 : if ( rURL.GetMap() )
1482 : {
1483 0 : IMapObject *pObject = pFly->GetFmt()->GetIMapObject( rPt, pFly );
1484 0 : if ( pObject && !pObject->GetURL().isEmpty() )
1485 : {
1486 0 : if( pURL )
1487 0 : *pURL = pObject->GetURL();
1488 0 : if ( bSetTargetFrameName && !pObject->GetTarget().isEmpty() )
1489 : {
1490 0 : bSetTargetFrameName = false;
1491 0 : *pTargetFrameName = pObject->GetTarget();
1492 : }
1493 0 : if ( bSetDescription )
1494 : {
1495 0 : bSetDescription = false;
1496 0 : *pDescription = pObject->GetAltText();
1497 : }
1498 0 : pRet = pFly->GetFmt();
1499 : }
1500 : }
1501 : else
1502 : {
1503 0 : if( pURL )
1504 : {
1505 0 : *pURL = rURL.GetURL();
1506 0 : if( rURL.IsServerMap() )
1507 : {
1508 : // append the relative pixel position !!
1509 0 : Point aPt( rPt );
1510 0 : aPt -= pFly->Frm().Pos();
1511 : // without MapMode-Offset, without Offset, o ... !!!!!
1512 : aPt = GetOut()->LogicToPixel(
1513 0 : aPt, MapMode( MAP_TWIP ) );
1514 0 : ((( *pURL += "?" ) += OUString::number( aPt.getX() ))
1515 0 : += "," ) += OUString::number(aPt.getY() );
1516 : }
1517 : }
1518 0 : pRet = pFly->GetFmt();
1519 : }
1520 0 : if ( bSetTargetFrameName )
1521 0 : *pTargetFrameName = rURL.GetTargetFrameName();
1522 0 : if ( bSetDescription )
1523 0 : *pDescription = pFly->GetFmt()->GetName();
1524 : }
1525 : }
1526 0 : pDView->SetHitTolerancePixel( nOld );
1527 0 : return pRet;
1528 : }
1529 :
1530 0 : const Graphic *SwFEShell::GetGrfAtPos( const Point &rPt,
1531 : OUString &rName, bool &rbLink ) const
1532 : {
1533 0 : if( !Imp()->HasDrawView() )
1534 0 : return 0;
1535 :
1536 : SdrObject* pObj;
1537 : SdrPageView* pPV;
1538 0 : SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
1539 :
1540 0 : if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPV ) && pObj->ISA(SwVirtFlyDrawObj) )
1541 : {
1542 0 : SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
1543 0 : if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
1544 : {
1545 0 : SwGrfNode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode();
1546 0 : if ( pNd )
1547 : {
1548 0 : if ( pNd->IsGrfLink() )
1549 : {
1550 : // halfway ready graphic?
1551 0 : ::sfx2::SvLinkSource* pLnkObj = pNd->GetLink()->GetObj();
1552 0 : if( pLnkObj && pLnkObj->IsPending() )
1553 0 : return 0;
1554 0 : rbLink = true;
1555 : }
1556 :
1557 0 : pNd->GetFileFilterNms( &rName, 0 );
1558 0 : if ( rName.isEmpty() )
1559 0 : rName = pFly->GetFmt()->GetName();
1560 0 : pNd->SwapIn( true );
1561 0 : return &pNd->GetGrf();
1562 : }
1563 : }
1564 : }
1565 0 : return 0;
1566 : }
1567 :
1568 0 : const SwFrmFmt* SwFEShell::GetFmtFromObj( const Point& rPt, SwRect** pRectToFill ) const
1569 : {
1570 0 : SwFrmFmt* pRet = 0;
1571 :
1572 0 : if( Imp()->HasDrawView() )
1573 : {
1574 : SdrObject* pObj;
1575 : SdrPageView* pPView;
1576 :
1577 0 : SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
1578 :
1579 0 : sal_uInt16 nOld = pDView->GetHitTolerancePixel();
1580 : // tolerance for Drawing-SS
1581 0 : pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
1582 :
1583 0 : if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE ) )
1584 : {
1585 : // first check it:
1586 0 : if ( pObj->ISA(SwVirtFlyDrawObj) )
1587 0 : pRet = ((SwVirtFlyDrawObj*)pObj)->GetFmt();
1588 0 : else if ( pObj->GetUserCall() ) //not for group objects
1589 0 : pRet = ((SwDrawContact*)pObj->GetUserCall())->GetFmt();
1590 0 : if(pRet && pRectToFill)
1591 0 : **pRectToFill = pObj->GetCurrentBoundRect();
1592 : }
1593 0 : pDView->SetHitTolerancePixel( nOld );
1594 : }
1595 0 : return pRet;
1596 : }
1597 :
1598 : // returns a format too, if the point is over the text of any fly
1599 0 : const SwFrmFmt* SwFEShell::GetFmtFromAnyObj( const Point& rPt ) const
1600 : {
1601 0 : const SwFrmFmt* pRet = GetFmtFromObj( rPt );
1602 0 : if( !pRet || RES_FLYFRMFMT == pRet->Which() )
1603 : {
1604 0 : SwPosition aPos( *GetCrsr()->GetPoint() );
1605 0 : Point aPt( rPt );
1606 0 : GetLayout()->GetCrsrOfst( &aPos, aPt );
1607 0 : SwCntntNode *pNd = aPos.nNode.GetNode().GetCntntNode();
1608 0 : SwFrm* pFrm = pNd->getLayoutFrm( GetLayout(), &rPt, 0, false )->FindFlyFrm();
1609 0 : pRet = pFrm ? ((SwLayoutFrm*)pFrm)->GetFmt() : 0;
1610 : }
1611 0 : return pRet;
1612 : }
1613 :
1614 0 : ObjCntType SwFEShell::GetObjCntType( const SdrObject& rObj ) const
1615 : {
1616 0 : ObjCntType eType = OBJCNT_NONE;
1617 :
1618 : // investigate 'master' drawing object, if method
1619 : // is called for a 'virtual' drawing object.
1620 : const SdrObject* pInvestigatedObj;
1621 0 : if ( rObj.ISA(SwDrawVirtObj) )
1622 : {
1623 0 : const SwDrawVirtObj* pDrawVirtObj = static_cast<const SwDrawVirtObj*>(&rObj);
1624 0 : pInvestigatedObj = &(pDrawVirtObj->GetReferencedObj());
1625 : }
1626 : else
1627 : {
1628 0 : pInvestigatedObj = &rObj;
1629 : }
1630 :
1631 0 : if( FmFormInventor == pInvestigatedObj->GetObjInventor() )
1632 : {
1633 0 : eType = OBJCNT_CONTROL;
1634 : uno::Reference< awt::XControlModel > xModel =
1635 0 : ((SdrUnoObj&)(*pInvestigatedObj)).GetUnoControlModel();
1636 0 : if( xModel.is() )
1637 : {
1638 0 : uno::Any aVal;
1639 0 : OUString sName("ButtonType");
1640 0 : uno::Reference< beans::XPropertySet > xSet(xModel, uno::UNO_QUERY);
1641 :
1642 0 : uno::Reference< beans::XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
1643 0 : if(xInfo->hasPropertyByName( sName ))
1644 : {
1645 0 : beans::Property xProperty = xInfo->getPropertyByName( sName );
1646 0 : aVal = xSet->getPropertyValue( sName );
1647 0 : if( aVal.getValue() && form::FormButtonType_URL == *((form::FormButtonType*)aVal.getValue()) )
1648 0 : eType = OBJCNT_URLBUTTON;
1649 0 : }
1650 0 : }
1651 : }
1652 0 : else if( pInvestigatedObj->ISA(SwVirtFlyDrawObj) )
1653 : {
1654 0 : SwFlyFrm *pFly = ((SwVirtFlyDrawObj&)(*pInvestigatedObj)).GetFlyFrm();
1655 0 : if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
1656 : {
1657 0 : if ( ((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode() )
1658 0 : eType = OBJCNT_GRF;
1659 : else
1660 0 : eType = OBJCNT_OLE;
1661 : }
1662 : else
1663 0 : eType = OBJCNT_FLY;
1664 : }
1665 0 : else if ( pInvestigatedObj->ISA( SdrObjGroup ) )
1666 : {
1667 0 : SwDrawContact* pDrawContact( dynamic_cast<SwDrawContact*>(GetUserCall( pInvestigatedObj ) ) );
1668 0 : if ( !pDrawContact )
1669 : {
1670 : OSL_FAIL( "<SwFEShell::GetObjCntType(..)> - missing draw contact object" );
1671 0 : eType = OBJCNT_NONE;
1672 : }
1673 : else
1674 : {
1675 0 : SwFrmFmt* pFrmFmt( pDrawContact->GetFmt() );
1676 0 : if ( !pFrmFmt )
1677 : {
1678 : OSL_FAIL( "<SwFEShell::GetObjCntType(..)> - missing frame format" );
1679 0 : eType = OBJCNT_NONE;
1680 : }
1681 0 : else if ( FLY_AS_CHAR != pFrmFmt->GetAnchor().GetAnchorId() )
1682 : {
1683 0 : eType = OBJCNT_GROUPOBJ;
1684 : }
1685 : }
1686 : }
1687 : else
1688 0 : eType = OBJCNT_SIMPLE;
1689 0 : return eType;
1690 : }
1691 :
1692 0 : ObjCntType SwFEShell::GetObjCntType( const Point &rPt, SdrObject *&rpObj ) const
1693 : {
1694 0 : ObjCntType eType = OBJCNT_NONE;
1695 :
1696 0 : if( Imp()->HasDrawView() )
1697 : {
1698 : SdrObject* pObj;
1699 : SdrPageView* pPView;
1700 :
1701 0 : SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
1702 :
1703 0 : sal_uInt16 nOld = pDView->GetHitTolerancePixel();
1704 : // tolerance for Drawing-SS
1705 0 : pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
1706 :
1707 0 : if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE ) )
1708 0 : eType = GetObjCntType( *(rpObj = pObj) );
1709 :
1710 0 : pDView->SetHitTolerancePixel( nOld );
1711 : }
1712 0 : return eType;
1713 : }
1714 :
1715 2339 : ObjCntType SwFEShell::GetObjCntTypeOfSelection( SdrObject** ppObj ) const
1716 : {
1717 2339 : ObjCntType eType = OBJCNT_NONE;
1718 :
1719 2339 : if( Imp()->HasDrawView() )
1720 : {
1721 2339 : const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1722 2339 : for( size_t i = 0, nE = rMrkList.GetMarkCount(); i < nE; ++i )
1723 : {
1724 0 : SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
1725 0 : if( !pObj )
1726 0 : continue;
1727 0 : ObjCntType eTmp = GetObjCntType( *pObj );
1728 0 : if( !i )
1729 : {
1730 0 : eType = eTmp;
1731 0 : if( ppObj ) *ppObj = pObj;
1732 : }
1733 0 : else if( eTmp != eType )
1734 : {
1735 0 : eType = OBJCNT_DONTCARE;
1736 : // once DontCare, always DontCare!
1737 0 : break;
1738 : }
1739 : }
1740 : }
1741 2339 : return eType;
1742 : }
1743 :
1744 0 : bool SwFEShell::ReplaceSdrObj( const OUString& rGrfName, const OUString& rFltName,
1745 : const Graphic* pGrf )
1746 : {
1747 0 : SET_CURR_SHELL( this );
1748 :
1749 0 : bool bRet = false;
1750 : const SdrMarkList *pMrkList;
1751 0 : if( Imp()->HasDrawView() && 1 ==
1752 0 : ( pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList())->GetMarkCount() )
1753 : {
1754 0 : SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
1755 0 : SwFrmFmt *pFmt = FindFrmFmt( pObj );
1756 :
1757 : // store attributes, then set the graphic
1758 0 : SfxItemSet aFrmSet( mpDoc->GetAttrPool(),
1759 0 : pFmt->GetAttrSet().GetRanges() );
1760 0 : aFrmSet.Set( pFmt->GetAttrSet() );
1761 :
1762 : // set size and position?
1763 0 : if( !pObj->ISA(SwVirtFlyDrawObj) )
1764 : {
1765 : // then let's do it:
1766 0 : const Rectangle &rBound = pObj->GetSnapRect();
1767 0 : Point aRelPos( pObj->GetRelativePos() );
1768 :
1769 0 : const long nWidth = rBound.Right() - rBound.Left();
1770 0 : const long nHeight= rBound.Bottom() - rBound.Top();
1771 : aFrmSet.Put( SwFmtFrmSize( ATT_MIN_SIZE,
1772 0 : std::max( nWidth, long(MINFLY) ),
1773 0 : std::max( nHeight, long(MINFLY) )));
1774 :
1775 0 : if( SfxItemState::SET != aFrmSet.GetItemState( RES_HORI_ORIENT ))
1776 0 : aFrmSet.Put( SwFmtHoriOrient( aRelPos.getX(), text::HoriOrientation::NONE, text::RelOrientation::FRAME ));
1777 :
1778 0 : if( SfxItemState::SET != aFrmSet.GetItemState( RES_VERT_ORIENT ))
1779 0 : aFrmSet.Put( SwFmtVertOrient( aRelPos.getY(), text::VertOrientation::NONE, text::RelOrientation::FRAME ));
1780 :
1781 : }
1782 :
1783 0 : pObj->GetOrdNum();
1784 :
1785 0 : StartAllAction();
1786 0 : StartUndo();
1787 :
1788 : // delete "Sdr-Object", insert the graphic instead
1789 0 : DelSelectedObj();
1790 :
1791 0 : GetDoc()->getIDocumentContentOperations().Insert( *GetCrsr(), rGrfName, rFltName, pGrf, &aFrmSet, NULL, NULL );
1792 :
1793 0 : EndUndo();
1794 0 : EndAllAction();
1795 0 : bRet = true;
1796 : }
1797 0 : return bRet;
1798 : }
1799 :
1800 0 : static sal_uInt16 SwFmtGetPageNum(const SwFlyFrmFmt * pFmt)
1801 : {
1802 : OSL_ENSURE(pFmt != NULL, "invalid argument");
1803 :
1804 0 : SwFlyFrm * pFrm = pFmt->GetFrm();
1805 :
1806 : sal_uInt16 aResult;
1807 :
1808 0 : if (pFrm != NULL)
1809 0 : aResult = pFrm->GetPhyPageNum();
1810 : else
1811 0 : aResult = pFmt->GetAnchor().GetPageNum();
1812 :
1813 0 : return aResult;
1814 : }
1815 :
1816 : #include <fmtcnct.hxx>
1817 :
1818 0 : void SwFEShell::GetConnectableFrmFmts(SwFrmFmt & rFmt,
1819 : const OUString & rReference,
1820 : bool bSuccessors,
1821 : ::std::vector< OUString > & aPrevPageVec,
1822 : ::std::vector< OUString > & aThisPageVec,
1823 : ::std::vector< OUString > & aNextPageVec,
1824 : ::std::vector< OUString > & aRestVec)
1825 : {
1826 0 : StartAction();
1827 :
1828 0 : SwFmtChain rChain = rFmt.GetChain();
1829 0 : SwFrmFmt * pOldChainNext = (SwFrmFmt *) rChain.GetNext();
1830 0 : SwFrmFmt * pOldChainPrev = (SwFrmFmt *) rChain.GetPrev();
1831 :
1832 0 : if (pOldChainNext)
1833 0 : mpDoc->Unchain(rFmt);
1834 :
1835 0 : if (pOldChainPrev)
1836 0 : mpDoc->Unchain(*pOldChainPrev);
1837 :
1838 0 : sal_uInt16 nCnt = mpDoc->GetFlyCount(FLYCNTTYPE_FRM);
1839 :
1840 : /* potential successors resp. predecessors */
1841 0 : ::std::vector< const SwFrmFmt * > aTmpSpzArray;
1842 :
1843 0 : mpDoc->FindFlyByName(rReference);
1844 :
1845 0 : for (sal_uInt16 n = 0; n < nCnt; n++)
1846 : {
1847 0 : const SwFrmFmt & rFmt1 = *(mpDoc->GetFlyNum(n, FLYCNTTYPE_FRM));
1848 :
1849 : /*
1850 : pFmt is a potential successor of rFmt if it is chainable after
1851 : rFmt.
1852 :
1853 : pFmt is a potential predecessor of rFmt if rFmt is chainable
1854 : after pFmt.
1855 : */
1856 :
1857 : int nChainState;
1858 :
1859 0 : if (bSuccessors)
1860 0 : nChainState = mpDoc->Chainable(rFmt, rFmt1);
1861 : else
1862 0 : nChainState = mpDoc->Chainable(rFmt1, rFmt);
1863 :
1864 0 : if (nChainState == SW_CHAIN_OK)
1865 : {
1866 0 : aTmpSpzArray.push_back(&rFmt1);
1867 :
1868 : }
1869 :
1870 : }
1871 :
1872 0 : if (aTmpSpzArray.size() > 0)
1873 : {
1874 0 : aPrevPageVec.clear();
1875 0 : aThisPageVec.clear();
1876 0 : aNextPageVec.clear();
1877 0 : aRestVec.clear();
1878 :
1879 : /* number of page rFmt resides on */
1880 0 : sal_uInt16 nPageNum = SwFmtGetPageNum((SwFlyFrmFmt *) &rFmt);
1881 :
1882 0 : ::std::vector< const SwFrmFmt * >::const_iterator aIt;
1883 :
1884 0 : for (aIt = aTmpSpzArray.begin(); aIt != aTmpSpzArray.end(); ++aIt)
1885 : {
1886 0 : const OUString aString = (*aIt)->GetName();
1887 :
1888 : /* rFmt is not a vaild successor or predecessor of
1889 : itself */
1890 0 : if (aString != rReference && aString != rFmt.GetName())
1891 : {
1892 : sal_uInt16 nNum1 =
1893 0 : SwFmtGetPageNum((SwFlyFrmFmt *) *aIt);
1894 :
1895 0 : if (nNum1 == nPageNum -1)
1896 0 : aPrevPageVec.push_back(aString);
1897 0 : else if (nNum1 == nPageNum)
1898 0 : aThisPageVec.push_back(aString);
1899 0 : else if (nNum1 == nPageNum + 1)
1900 0 : aNextPageVec.push_back(aString);
1901 : else
1902 0 : aRestVec.push_back(aString);
1903 : }
1904 0 : }
1905 :
1906 : }
1907 :
1908 0 : if (pOldChainNext)
1909 0 : mpDoc->Chain(rFmt, *pOldChainNext);
1910 :
1911 0 : if (pOldChainPrev)
1912 0 : mpDoc->Chain(*pOldChainPrev, rFmt);
1913 :
1914 0 : EndAction();
1915 0 : }
1916 :
1917 : // #i73249#
1918 0 : OUString SwFEShell::GetObjTitle() const
1919 : {
1920 0 : if ( Imp()->HasDrawView() )
1921 : {
1922 0 : const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
1923 0 : if ( pMrkList->GetMarkCount() == 1 )
1924 : {
1925 0 : const SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
1926 0 : const SwFrmFmt* pFmt = FindFrmFmt( pObj );
1927 0 : if ( pFmt->Which() == RES_FLYFRMFMT )
1928 : {
1929 0 : return static_cast<const SwFlyFrmFmt*>(pFmt)->GetObjTitle();
1930 : }
1931 0 : return pObj->GetTitle();
1932 : }
1933 : }
1934 :
1935 0 : return OUString();
1936 : }
1937 :
1938 0 : void SwFEShell::SetObjTitle( const OUString& rTitle )
1939 : {
1940 0 : if ( Imp()->HasDrawView() )
1941 : {
1942 0 : const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
1943 0 : if ( pMrkList->GetMarkCount() == 1 )
1944 : {
1945 0 : SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
1946 0 : SwFrmFmt* pFmt = FindFrmFmt( pObj );
1947 0 : if ( pFmt->Which() == RES_FLYFRMFMT )
1948 : {
1949 0 : GetDoc()->SetFlyFrmTitle( dynamic_cast<SwFlyFrmFmt&>(*pFmt),
1950 0 : rTitle );
1951 : }
1952 : else
1953 : {
1954 0 : pObj->SetTitle( rTitle );
1955 : }
1956 : }
1957 : }
1958 0 : }
1959 :
1960 0 : OUString SwFEShell::GetObjDescription() const
1961 : {
1962 0 : if ( Imp()->HasDrawView() )
1963 : {
1964 0 : const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
1965 0 : if ( pMrkList->GetMarkCount() == 1 )
1966 : {
1967 0 : const SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
1968 0 : const SwFrmFmt* pFmt = FindFrmFmt( pObj );
1969 0 : if ( pFmt->Which() == RES_FLYFRMFMT )
1970 : {
1971 0 : return dynamic_cast<const SwFlyFrmFmt&>(*pFmt).GetObjDescription();
1972 : }
1973 0 : return pObj->GetDescription();
1974 : }
1975 : }
1976 :
1977 0 : return OUString();
1978 : }
1979 :
1980 0 : void SwFEShell::SetObjDescription( const OUString& rDescription )
1981 : {
1982 0 : if ( Imp()->HasDrawView() )
1983 : {
1984 0 : const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
1985 0 : if ( pMrkList->GetMarkCount() == 1 )
1986 : {
1987 0 : SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
1988 0 : SwFrmFmt* pFmt = FindFrmFmt( pObj );
1989 0 : if ( pFmt->Which() == RES_FLYFRMFMT )
1990 : {
1991 0 : GetDoc()->SetFlyFrmDescription(dynamic_cast<SwFlyFrmFmt&>(*pFmt),
1992 0 : rDescription);
1993 : }
1994 : else
1995 : {
1996 0 : pObj->SetDescription( rDescription );
1997 : }
1998 : }
1999 : }
2000 0 : }
2001 :
2002 0 : void SwFEShell::AlignFormulaToBaseline( const uno::Reference < embed::XEmbeddedObject >& xObj, SwFlyFrm * pFly )
2003 : {
2004 : #if OSL_DEBUG_LEVEL > 0
2005 : SvGlobalName aCLSID( xObj->getClassID() );
2006 : const bool bStarMath = ( SotExchange::IsMath( aCLSID ) != 0 );
2007 : OSL_ENSURE( bStarMath, "AlignFormulaToBaseline should only be called for Math objects" );
2008 :
2009 : if ( !bStarMath )
2010 : return;
2011 : #endif
2012 :
2013 0 : if (!pFly)
2014 0 : pFly = FindFlyFrm( xObj );
2015 : OSL_ENSURE( pFly , "No fly frame!" );
2016 0 : SwFrmFmt * pFrmFmt = pFly ? pFly->GetFmt() : 0;
2017 :
2018 : // baseline to baseline alignment should only be applied to formulas anchored as char
2019 0 : if ( pFly && pFrmFmt && FLY_AS_CHAR == pFrmFmt->GetAnchor().GetAnchorId() )
2020 : {
2021 : // get baseline from Math object
2022 0 : uno::Any aBaseline;
2023 0 : if( svt::EmbeddedObjectRef::TryRunningState( xObj ) )
2024 : {
2025 0 : uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
2026 0 : if ( xSet.is() )
2027 : {
2028 : try
2029 : {
2030 0 : aBaseline = xSet->getPropertyValue("BaseLine");
2031 : }
2032 0 : catch ( uno::Exception& )
2033 : {
2034 : OSL_FAIL( "Baseline could not be retrieved from Starmath!" );
2035 : }
2036 0 : }
2037 : }
2038 :
2039 0 : sal_Int32 nBaseline = ::comphelper::getINT32(aBaseline);
2040 0 : const MapMode aSourceMapMode( MAP_100TH_MM );
2041 0 : const MapMode aTargetMapMode( MAP_TWIP );
2042 0 : nBaseline = OutputDevice::LogicToLogic( nBaseline, aSourceMapMode.GetMapUnit(), aTargetMapMode.GetMapUnit() );
2043 :
2044 : OSL_ENSURE( nBaseline > 0, "Wrong value of Baseline while retrieving from Starmath!" );
2045 : //nBaseline must be moved by aPrt position
2046 0 : const SwFlyFrmFmt *pFlyFrmFmt = pFly->GetFmt();
2047 : OSL_ENSURE( pFlyFrmFmt, "fly frame format missing!" );
2048 0 : if ( pFlyFrmFmt )
2049 0 : nBaseline += pFlyFrmFmt->GetLastFlyFrmPrtRectPos().Y();
2050 :
2051 0 : const SwFmtVertOrient &rVert = pFrmFmt->GetVertOrient();
2052 0 : SwFmtVertOrient aVert( rVert );
2053 0 : aVert.SetPos( -nBaseline );
2054 0 : aVert.SetVertOrient( com::sun::star::text::VertOrientation::NONE );
2055 :
2056 0 : pFrmFmt->LockModify();
2057 0 : pFrmFmt->SetFmtAttr( aVert );
2058 0 : pFrmFmt->UnlockModify();
2059 0 : pFly->InvalidatePos();
2060 : }
2061 0 : }
2062 :
2063 0 : void SwFEShell::AlignAllFormulasToBaseline()
2064 : {
2065 0 : StartAllAction();
2066 :
2067 : SwStartNode *pStNd;
2068 0 : SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
2069 0 : while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
2070 : {
2071 0 : ++aIdx;
2072 0 : SwOLENode *pOleNode = dynamic_cast< SwOLENode * >( &aIdx.GetNode() );
2073 0 : if ( pOleNode )
2074 : {
2075 0 : const uno::Reference < embed::XEmbeddedObject > & xObj( pOleNode->GetOLEObj().GetOleRef() );
2076 0 : if (xObj.is())
2077 : {
2078 0 : SvGlobalName aCLSID( xObj->getClassID() );
2079 0 : if ( SotExchange::IsMath( aCLSID ) )
2080 0 : AlignFormulaToBaseline( xObj );
2081 0 : }
2082 : }
2083 :
2084 0 : aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
2085 : }
2086 :
2087 0 : EndAllAction();
2088 270 : }
2089 :
2090 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|