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 :
22 : #include <vcl/graph.hxx>
23 : #include <sot/formats.hxx>
24 : #include <sot/storage.hxx>
25 : #include <unotools/pathoptions.hxx>
26 : #include <sfx2/dispatch.hxx>
27 : #include <sfx2/docfile.hxx>
28 : #include <sfx2/viewsh.hxx>
29 : #include <svx/xexch.hxx>
30 : #include <svx/xflasit.hxx>
31 : #include <svx/xfillit0.hxx>
32 : #include <svx/xflclit.hxx>
33 : #include <editeng/brushitem.hxx>
34 : #include <svx/svdocapt.hxx>
35 : #include <svx/svdouno.hxx>
36 : #include <svx/xfillit.hxx>
37 : #include <svx/svdpage.hxx>
38 : #include <svx/svdogrp.hxx>
39 : #include <svx/xoutbmp.hxx>
40 : #include <svx/svdoole2.hxx>
41 : #include <svx/fmmodel.hxx>
42 : #include <svx/unomodel.hxx>
43 : #include <svx/svditer.hxx>
44 : #include <svx/svdograf.hxx>
45 : #include <unotools/streamwrap.hxx>
46 : #include <fmtanchr.hxx>
47 : #include <fmtcntnt.hxx>
48 : #include <fmtornt.hxx>
49 : #include <fmtflcnt.hxx>
50 : #include <frmfmt.hxx>
51 : #include <docary.hxx>
52 : #include <txtfrm.hxx>
53 : #include <txtflcnt.hxx>
54 : #include <fesh.hxx>
55 : #include <doc.hxx>
56 : #include <IDocumentUndoRedo.hxx>
57 : #include <IDocumentDrawModelAccess.hxx>
58 : #include <IDocumentRedlineAccess.hxx>
59 : #include <DocumentFieldsManager.hxx>
60 : #include <IDocumentLayoutAccess.hxx>
61 : #include <rootfrm.hxx>
62 : #include <ndtxt.hxx>
63 : #include <pam.hxx>
64 : #include <tblsel.hxx>
65 : #include <swtable.hxx>
66 : #include <flyfrm.hxx>
67 : #include <pagefrm.hxx>
68 : #include <fldbas.hxx>
69 : #include <edimp.hxx>
70 : #include <swundo.hxx>
71 : #include <viewimp.hxx>
72 : #include <dview.hxx>
73 : #include <dcontact.hxx>
74 : #include <dflyobj.hxx>
75 : #include <docsh.hxx>
76 : #include <pagedesc.hxx>
77 : #include <mvsave.hxx>
78 : #include <textboxhelper.hxx>
79 : #include <vcl/virdev.hxx>
80 : #include <svx/svdundo.hxx>
81 :
82 : using namespace ::com::sun::star;
83 :
84 : // Copy for the internal clipboard. Copies all selections to the clipboard.
85 6 : bool SwFEShell::Copy( SwDoc* pClpDoc, const OUString* pNewClpTxt )
86 : {
87 : OSL_ENSURE( pClpDoc, "kein Clipboard-Dokument" );
88 :
89 6 : pClpDoc->GetIDocumentUndoRedo().DoUndo(false); // always false!
90 :
91 : // delete content if ClpDocument contains content
92 6 : SwNodeIndex aSttIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 );
93 6 : SwTxtNode* pTxtNd = aSttIdx.GetNode().GetTxtNode();
94 12 : if (!pTxtNd || !pTxtNd->GetTxt().isEmpty() ||
95 6 : aSttIdx.GetIndex()+1 != pClpDoc->GetNodes().GetEndOfContent().GetIndex() )
96 : {
97 0 : pClpDoc->GetNodes().Delete( aSttIdx,
98 0 : pClpDoc->GetNodes().GetEndOfContent().GetIndex() - aSttIdx.GetIndex() );
99 0 : pTxtNd = pClpDoc->GetNodes().MakeTxtNode( aSttIdx,
100 0 : (SwTxtFmtColl*)pClpDoc->GetDfltTxtFmtColl() );
101 0 : aSttIdx--;
102 : }
103 :
104 : // also delete surrounding FlyFrames if any
105 6 : for( sal_uInt16 n = 0; n < pClpDoc->GetSpzFrmFmts()->size(); ++n )
106 : {
107 0 : SwFlyFrmFmt* pFly = (SwFlyFrmFmt*)(*pClpDoc->GetSpzFrmFmts())[n];
108 0 : pClpDoc->getIDocumentLayoutAccess().DelLayoutFmt( pFly );
109 : }
110 6 : pClpDoc->GetDocumentFieldsManager().GCFieldTypes(); // delete the FieldTypes
111 :
112 : // if a string was passed, copy it to the clipboard-
113 : // document. Then also the Calculator can use the internal
114 : // clipboard
115 6 : if( pNewClpTxt )
116 : {
117 0 : pTxtNd->InsertText( *pNewClpTxt, SwIndex( pTxtNd ) );
118 0 : return true; // das wars.
119 : }
120 :
121 6 : pClpDoc->getIDocumentFieldsAccess().LockExpFlds();
122 6 : pClpDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( nsRedlineMode_t::REDLINE_DELETE_REDLINES );
123 : bool bRet;
124 :
125 : // do we want to copy a FlyFrame?
126 6 : if( IsFrmSelected() )
127 : {
128 : // get the FlyFormat
129 0 : SwFlyFrm* pFly = FindFlyFrm();
130 0 : SwFrmFmt* pFlyFmt = pFly->GetFmt();
131 0 : SwFmtAnchor aAnchor( pFlyFmt->GetAnchor() );
132 :
133 0 : if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
134 0 : (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
135 0 : (FLY_AT_FLY == aAnchor.GetAnchorId()) ||
136 0 : (FLY_AS_CHAR == aAnchor.GetAnchorId()))
137 : {
138 0 : SwPosition aPos( aSttIdx );
139 0 : if ( FLY_AS_CHAR == aAnchor.GetAnchorId() )
140 : {
141 0 : aPos.nContent.Assign( pTxtNd, 0 );
142 : }
143 0 : aAnchor.SetAnchor( &aPos );
144 : }
145 0 : pFlyFmt = pClpDoc->getIDocumentLayoutAccess().CopyLayoutFmt( *pFlyFmt, aAnchor, true, true );
146 :
147 : // assure the "RootFmt" is the first element in Spz-Array
148 : // (if necessary Flys were copied in Flys)
149 0 : SwFrmFmts& rSpzFrmFmts = *(SwFrmFmts*)pClpDoc->GetSpzFrmFmts();
150 0 : if( rSpzFrmFmts[ 0 ] != pFlyFmt )
151 : {
152 0 : SwFrmFmts::iterator it = std::find( rSpzFrmFmts.begin(), rSpzFrmFmts.end(), pFlyFmt );
153 : OSL_ENSURE( it != rSpzFrmFmts.end(), "Fly not contained in Spz-Array" );
154 :
155 0 : rSpzFrmFmts.erase( it );
156 0 : rSpzFrmFmts.insert( rSpzFrmFmts.begin(), pFlyFmt );
157 : }
158 :
159 0 : if ( FLY_AS_CHAR == aAnchor.GetAnchorId() )
160 : {
161 : // JP 13.02.99 Bug 61863: if a frameselection is passed to the
162 : // clipboard, it should be found at pasting. Therefore
163 : // the copied TextAttribut should be removed in the node
164 : // otherwise it will be recognised as TextSelektion
165 0 : const SwIndex& rIdx = pFlyFmt->GetAnchor().GetCntntAnchor()->nContent;
166 : SwTxtFlyCnt *const pTxtFly = static_cast<SwTxtFlyCnt *>(
167 : pTxtNd->GetTxtAttrForCharAt(
168 0 : rIdx.GetIndex(), RES_TXTATR_FLYCNT));
169 0 : if( pTxtFly )
170 : {
171 0 : ((SwFmtFlyCnt&)pTxtFly->GetFlyCnt()).SetFlyFmt( 0 );
172 0 : pTxtNd->EraseText( rIdx, 1 );
173 : }
174 : }
175 0 : bRet = true;
176 : }
177 6 : else if ( IsObjSelected() )
178 : {
179 2 : SwPosition aPos( aSttIdx, SwIndex( pTxtNd, 0 ));
180 2 : const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
181 4 : for ( size_t i = 0; i < rMrkList.GetMarkCount(); ++i )
182 : {
183 2 : SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
184 :
185 4 : if( Imp()->GetDrawView()->IsGroupEntered() ||
186 2 : ( !pObj->GetUserCall() && pObj->GetUpGroup()) )
187 : {
188 0 : SfxItemSet aSet( pClpDoc->GetAttrPool(), aFrmFmtSetRange );
189 :
190 0 : SwFmtAnchor aAnchor( FLY_AT_PARA );
191 0 : aAnchor.SetAnchor( &aPos );
192 0 : aSet.Put( aAnchor );
193 :
194 : SdrObject *const pNew =
195 0 : pClpDoc->CloneSdrObj( *pObj, false, true );
196 :
197 0 : SwPaM aTemp(aPos);
198 0 : pClpDoc->getIDocumentContentOperations().InsertDrawObj(aTemp, *pNew, aSet );
199 : }
200 : else
201 : {
202 2 : SwDrawContact *pContact = (SwDrawContact*)GetUserCall( pObj );
203 2 : SwFrmFmt *pFmt = pContact->GetFmt();
204 2 : SwFmtAnchor aAnchor( pFmt->GetAnchor() );
205 4 : if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
206 0 : (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
207 2 : (FLY_AT_FLY == aAnchor.GetAnchorId()) ||
208 0 : (FLY_AS_CHAR == aAnchor.GetAnchorId()))
209 : {
210 2 : aAnchor.SetAnchor( &aPos );
211 : }
212 :
213 2 : pClpDoc->getIDocumentLayoutAccess().CopyLayoutFmt( *pFmt, aAnchor, true, true );
214 : }
215 : }
216 2 : bRet = true;
217 : }
218 : else
219 4 : bRet = _CopySelToDoc( pClpDoc, 0 ); // copy the selections
220 :
221 6 : pClpDoc->getIDocumentRedlineAccess().SetRedlineMode_intern((RedlineMode_t)0 );
222 6 : pClpDoc->getIDocumentFieldsAccess().UnlockExpFlds();
223 6 : if( !pClpDoc->getIDocumentFieldsAccess().IsExpFldsLocked() )
224 4 : pClpDoc->getIDocumentFieldsAccess().UpdateExpFlds(NULL, true);
225 :
226 6 : return bRet;
227 : }
228 :
229 0 : static const Point &lcl_FindBasePos( const SwFrm *pFrm, const Point &rPt )
230 : {
231 0 : const SwFrm *pF = pFrm;
232 0 : while ( pF && !pF->Frm().IsInside( rPt ) )
233 : {
234 0 : if ( pF->IsCntntFrm() )
235 0 : pF = ((SwCntntFrm*)pF)->GetFollow();
236 : else
237 0 : pF = 0;
238 : }
239 0 : if ( pF )
240 0 : return pF->Frm().Pos();
241 : else
242 0 : return pFrm->Frm().Pos();
243 : }
244 :
245 0 : static bool lcl_SetAnchor( const SwPosition& rPos, const SwNode& rNd, SwFlyFrm* pFly,
246 : const Point& rInsPt, SwFEShell& rDestShell, SwFmtAnchor& rAnchor,
247 : Point& rNewPos, bool bCheckFlyRecur )
248 : {
249 0 : bool bRet = true;
250 0 : rAnchor.SetAnchor( &rPos );
251 0 : SwCntntFrm* pTmpFrm = rNd.GetCntntNode()->getLayoutFrm( rDestShell.GetLayout(), &rInsPt, 0, false );
252 0 : SwFlyFrm *pTmpFly = pTmpFrm->FindFlyFrm();
253 0 : if( pTmpFly && bCheckFlyRecur && pFly->IsUpperOf( *pTmpFly ) )
254 : {
255 0 : bRet = false;
256 : }
257 0 : else if ( FLY_AT_FLY == rAnchor.GetAnchorId() )
258 : {
259 0 : if( pTmpFly )
260 : {
261 0 : const SwNodeIndex& rIdx = *pTmpFly->GetFmt()->GetCntnt().GetCntntIdx();
262 0 : SwPosition aPos( rIdx );
263 0 : rAnchor.SetAnchor( &aPos );
264 0 : rNewPos = pTmpFly->Frm().Pos();
265 : }
266 : else
267 : {
268 0 : rAnchor.SetType( FLY_AT_PAGE );
269 0 : rAnchor.SetPageNum( rDestShell.GetPageNumber( rInsPt ) );
270 0 : const SwFrm *pPg = pTmpFrm->FindPageFrm();
271 0 : rNewPos = pPg->Frm().Pos();
272 : }
273 : }
274 : else
275 0 : rNewPos = ::lcl_FindBasePos( pTmpFrm, rInsPt );
276 0 : return bRet;
277 : }
278 :
279 0 : bool SwFEShell::CopyDrawSel( SwFEShell* pDestShell, const Point& rSttPt,
280 : const Point& rInsPt, bool bIsMove, bool bSelectInsert )
281 : {
282 0 : bool bRet = true;
283 :
284 : // The list should be copied, because below new objects will be selected
285 0 : const SdrMarkList aMrkList( Imp()->GetDrawView()->GetMarkedObjectList() );
286 0 : const size_t nMarkCount = aMrkList.GetMarkCount();
287 0 : if( !pDestShell->Imp()->GetDrawView() )
288 : // should create it now
289 0 : pDestShell->MakeDrawView();
290 0 : else if( bSelectInsert )
291 0 : pDestShell->Imp()->GetDrawView()->UnmarkAll();
292 :
293 0 : SdrPageView *pDestPgView = pDestShell->Imp()->GetPageView(),
294 0 : *pSrcPgView = Imp()->GetPageView();
295 0 : SwDrawView *pDestDrwView = pDestShell->Imp()->GetDrawView(),
296 0 : *pSrcDrwView = Imp()->GetDrawView();
297 0 : SwDoc* pDestDoc = pDestShell->GetDoc();
298 :
299 0 : Size aSiz( rInsPt.X() - rSttPt.X(), rInsPt.Y() - rSttPt.Y() );
300 0 : for( size_t i = 0; i < nMarkCount; ++i )
301 : {
302 0 : SdrObject *pObj = aMrkList.GetMark( i )->GetMarkedSdrObj();
303 :
304 0 : SwDrawContact *pContact = (SwDrawContact*)GetUserCall( pObj );
305 0 : SwFrmFmt *pFmt = pContact->GetFmt();
306 0 : const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
307 :
308 0 : bool bInsWithFmt = true;
309 :
310 0 : if( pDestDrwView->IsGroupEntered() )
311 : {
312 : // insert into the group, when it belongs to an entered group
313 : // or when the object is not anchored as a character
314 0 : if( pSrcDrwView->IsGroupEntered() ||
315 0 : (FLY_AS_CHAR != rAnchor.GetAnchorId()) )
316 :
317 : {
318 0 : SdrObject* pNew = pDestDoc->CloneSdrObj( *pObj, bIsMove &&
319 0 : GetDoc() == pDestDoc, false );
320 0 : pNew->NbcMove( aSiz );
321 0 : pDestDrwView->InsertObjectAtView( pNew, *pDestPgView );
322 0 : bInsWithFmt = false;
323 : }
324 : }
325 :
326 0 : if( bInsWithFmt )
327 : {
328 0 : SwFmtAnchor aAnchor( rAnchor );
329 0 : Point aNewAnch;
330 :
331 0 : if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
332 0 : (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
333 0 : (FLY_AT_FLY == aAnchor.GetAnchorId()) ||
334 0 : (FLY_AS_CHAR == aAnchor.GetAnchorId()))
335 : {
336 0 : if ( this == pDestShell )
337 : {
338 : // same shell? Then request the position
339 : // from the passed DocumentPosition
340 0 : SwPosition aPos( *GetCrsr()->GetPoint() );
341 0 : Point aPt( rInsPt );
342 0 : aPt -= rSttPt - pObj->GetSnapRect().TopLeft();
343 0 : SwCrsrMoveState aState( MV_SETONLYTEXT );
344 0 : GetLayout()->GetCrsrOfst( &aPos, aPt, &aState );
345 : const SwNode *pNd;
346 0 : if( (pNd = &aPos.nNode.GetNode())->IsNoTxtNode() )
347 0 : bRet = false;
348 : else
349 : bRet = ::lcl_SetAnchor( aPos, *pNd, 0, rInsPt,
350 0 : *pDestShell, aAnchor, aNewAnch, false );
351 : }
352 : else
353 : {
354 0 : SwPaM *pCrsr = pDestShell->GetCrsr();
355 0 : if( pCrsr->GetNode().IsNoTxtNode() )
356 0 : bRet = false;
357 : else
358 0 : bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(),
359 0 : pCrsr->GetNode(), 0, rInsPt,
360 : *pDestShell, aAnchor,
361 0 : aNewAnch, false );
362 : }
363 : }
364 0 : else if ( FLY_AT_PAGE == aAnchor.GetAnchorId() )
365 : {
366 0 : aAnchor.SetPageNum( pDestShell->GetPageNumber( rInsPt ) );
367 0 : const SwRootFrm* pTmpRoot = pDestShell->GetLayout();
368 0 : const SwFrm* pPg = pTmpRoot->GetPageAtPos( rInsPt, 0, true );
369 0 : if ( pPg )
370 0 : aNewAnch = pPg->Frm().Pos();
371 : }
372 :
373 0 : if( bRet )
374 : {
375 0 : if( pSrcDrwView->IsGroupEntered() ||
376 0 : ( !pObj->GetUserCall() && pObj->GetUpGroup()) )
377 : {
378 0 : SfxItemSet aSet( pDestDoc->GetAttrPool(),aFrmFmtSetRange);
379 0 : aSet.Put( aAnchor );
380 0 : SdrObject* pNew = pDestDoc->CloneSdrObj( *pObj, bIsMove &&
381 0 : GetDoc() == pDestDoc, true );
382 0 : pFmt = pDestDoc->getIDocumentContentOperations().InsertDrawObj( *pDestShell->GetCrsr(), *pNew, aSet );
383 : }
384 : else
385 0 : pFmt = pDestDoc->getIDocumentLayoutAccess().CopyLayoutFmt( *pFmt, aAnchor, true, true );
386 :
387 : // Can be 0, as Draws are not allowed in Headers/Footers
388 0 : if ( pFmt )
389 : {
390 0 : SdrObject* pNew = pFmt->FindSdrObject();
391 0 : if ( FLY_AS_CHAR != aAnchor.GetAnchorId() )
392 : {
393 0 : Point aPos( rInsPt );
394 0 : aPos -= aNewAnch;
395 0 : aPos -= rSttPt - pObj->GetSnapRect().TopLeft();
396 : // OD 2004-04-05 #i26791# - change attributes instead of
397 : // direct positioning
398 0 : pFmt->SetFmtAttr( SwFmtHoriOrient( aPos.getX(), text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
399 0 : pFmt->SetFmtAttr( SwFmtVertOrient( aPos.getY(), text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
400 : // #i47455# - notify draw frame format
401 : // that position attributes are already set.
402 0 : if ( pFmt->ISA(SwDrawFrmFmt) )
403 : {
404 0 : static_cast<SwDrawFrmFmt*>(pFmt)->PosAttrSet();
405 : }
406 : }
407 0 : if( bSelectInsert )
408 0 : pDestDrwView->MarkObj( pNew, pDestPgView );
409 : }
410 0 : }
411 : }
412 : }
413 :
414 0 : if ( bIsMove && bRet )
415 : {
416 0 : if( pDestShell == this )
417 : {
418 0 : const SdrMarkList aList( pSrcDrwView->GetMarkedObjectList() );
419 0 : pSrcDrwView->UnmarkAll();
420 :
421 0 : for ( size_t i = 0, nMrkCnt = aMrkList.GetMarkCount(); i < nMrkCnt; ++i )
422 : {
423 0 : SdrObject *pObj = aMrkList.GetMark( i )->GetMarkedSdrObj();
424 0 : pSrcDrwView->MarkObj( pObj, pSrcPgView );
425 : }
426 0 : DelSelectedObj();
427 0 : for ( size_t i = 0, nMrkCnt = aList.GetMarkCount(); i < nMrkCnt; ++i )
428 : {
429 0 : SdrObject *pObj = aList.GetMark( i )->GetMarkedSdrObj();
430 0 : pSrcDrwView->MarkObj( pObj, pSrcPgView );
431 0 : }
432 : }
433 : else
434 0 : DelSelectedObj();
435 : }
436 :
437 0 : return bRet;
438 : }
439 :
440 0 : bool SwFEShell::Copy( SwFEShell* pDestShell, const Point& rSttPt,
441 : const Point& rInsPt, bool bIsMove, bool bSelectInsert )
442 : {
443 0 : bool bRet = false;
444 :
445 : OSL_ENSURE( pDestShell, "Copy without DestShell." );
446 : OSL_ENSURE( this == pDestShell || !pDestShell->IsObjSelected(),
447 : "Dest-Shell cannot be in Obj-Mode" );
448 :
449 0 : SET_CURR_SHELL( pDestShell );
450 :
451 0 : pDestShell->StartAllAction();
452 0 : pDestShell->GetDoc()->getIDocumentFieldsAccess().LockExpFlds();
453 :
454 : // Shift references
455 0 : bool bCopyIsMove = mpDoc->IsCopyIsMove();
456 0 : if( bIsMove )
457 : // set a flag in Doc, handled in TextNodes
458 0 : mpDoc->SetCopyIsMove( true );
459 :
460 0 : RedlineMode_t eOldRedlMode = pDestShell->GetDoc()->getIDocumentRedlineAccess().GetRedlineMode();
461 0 : pDestShell->GetDoc()->getIDocumentRedlineAccess().SetRedlineMode_intern( (RedlineMode_t)(eOldRedlMode | nsRedlineMode_t::REDLINE_DELETE_REDLINES));
462 :
463 : // If there are table formulas in the area, then display the table first
464 : // so that the table formula can calculate a new value first
465 : // (individual boxes in the area are retrieved via the layout)
466 0 : SwFieldType* pTblFldTyp = pDestShell->GetDoc()->getIDocumentFieldsAccess().GetSysFldType( RES_TABLEFLD );
467 :
468 0 : if( IsFrmSelected() )
469 : {
470 0 : SwFlyFrm* pFly = FindFlyFrm();
471 0 : SwFrmFmt* pFlyFmt = pFly->GetFmt();
472 0 : SwFmtAnchor aAnchor( pFlyFmt->GetAnchor() );
473 0 : bRet = true;
474 0 : Point aNewAnch;
475 :
476 0 : if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
477 0 : (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
478 0 : (FLY_AT_FLY == aAnchor.GetAnchorId()) ||
479 0 : (FLY_AS_CHAR == aAnchor.GetAnchorId()))
480 : {
481 0 : if ( this == pDestShell )
482 : {
483 : // same shell? Then request the position
484 : // from the passed DocumentPosition
485 0 : SwPosition aPos( *GetCrsr()->GetPoint() );
486 0 : Point aPt( rInsPt );
487 0 : aPt -= rSttPt - pFly->Frm().Pos();
488 0 : SwCrsrMoveState aState( MV_SETONLYTEXT );
489 0 : GetLayout()->GetCrsrOfst( &aPos, aPt, &aState );
490 : const SwNode *pNd;
491 0 : if( (pNd = &aPos.nNode.GetNode())->IsNoTxtNode() )
492 0 : bRet = false;
493 : else
494 : {
495 : // do not copy in itself
496 0 : const SwNodeIndex *pTmp = pFlyFmt->GetCntnt().GetCntntIdx();
497 0 : if ( aPos.nNode > *pTmp && aPos.nNode <
498 0 : pTmp->GetNode().EndOfSectionIndex() )
499 : {
500 0 : bRet = false;
501 : }
502 : else
503 : bRet = ::lcl_SetAnchor( aPos, *pNd, pFly, rInsPt,
504 0 : *pDestShell, aAnchor, aNewAnch, true );
505 0 : }
506 : }
507 : else
508 : {
509 0 : const SwPaM *pCrsr = pDestShell->GetCrsr();
510 0 : if( pCrsr->GetNode().IsNoTxtNode() )
511 0 : bRet = false;
512 : else
513 0 : bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(), pCrsr->GetNode(),
514 : pFly, rInsPt, *pDestShell, aAnchor,
515 0 : aNewAnch, GetDoc() == pDestShell->GetDoc());
516 : }
517 : }
518 0 : else if ( FLY_AT_PAGE == aAnchor.GetAnchorId() )
519 : {
520 0 : aAnchor.SetPageNum( pDestShell->GetPageNumber( rInsPt ) );
521 0 : const SwRootFrm* pTmpRoot = pDestShell->GetLayout();
522 0 : const SwFrm* pPg = pTmpRoot->GetPageAtPos( rInsPt, 0, true );
523 0 : if ( pPg )
524 0 : aNewAnch = pPg->Frm().Pos();
525 : }
526 : else {
527 : OSL_ENSURE( false, "what anchor is it?" );
528 : }
529 :
530 0 : if( bRet )
531 : {
532 0 : SwFrmFmt *pOldFmt = pFlyFmt;
533 0 : pFlyFmt = pDestShell->GetDoc()->getIDocumentLayoutAccess().CopyLayoutFmt( *pFlyFmt, aAnchor, true, true );
534 :
535 0 : if ( FLY_AS_CHAR != aAnchor.GetAnchorId() )
536 : {
537 0 : Point aPos( rInsPt );
538 0 : aPos -= aNewAnch;
539 0 : aPos -= rSttPt - pFly->Frm().Pos();
540 0 : pFlyFmt->SetFmtAttr( SwFmtHoriOrient( aPos.getX(),text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
541 0 : pFlyFmt->SetFmtAttr( SwFmtVertOrient( aPos.getY(),text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
542 : }
543 :
544 0 : const Point aPt( pDestShell->GetCrsrDocPos() );
545 :
546 0 : if( bIsMove )
547 0 : GetDoc()->getIDocumentLayoutAccess().DelLayoutFmt( pOldFmt );
548 :
549 : // only select if it can be shifted/copied in the same shell
550 0 : if( bSelectInsert )
551 : {
552 0 : SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFlyFmt)->GetFrm( &aPt, false );
553 0 : if( pFlyFrm )
554 : {
555 : //JP 12.05.98: should this be in SelectFlyFrm???
556 0 : pDestShell->Imp()->GetDrawView()->UnmarkAll();
557 0 : pDestShell->SelectFlyFrm( *pFlyFrm, true );
558 : }
559 : }
560 :
561 0 : if( this != pDestShell && !pDestShell->HasShFcs() )
562 0 : pDestShell->Imp()->GetDrawView()->hideMarkHandles();
563 0 : }
564 : }
565 0 : else if ( IsObjSelected() )
566 0 : bRet = CopyDrawSel( pDestShell, rSttPt, rInsPt, bIsMove, bSelectInsert );
567 0 : else if( IsTableMode() )
568 : {
569 : // Copy parts from a table: create a table with the same
570 : // width as the original and copy the selected boxes.
571 : // Sizes will be corrected by percentage.
572 :
573 : // find boxes via the layout
574 : const SwTableNode* pTblNd;
575 0 : SwSelBoxes aBoxes;
576 0 : GetTblSel( *this, aBoxes );
577 0 : if( !aBoxes.empty() &&
578 0 : 0 != (pTblNd = aBoxes[0]->GetSttNd()->FindTableNode()) )
579 : {
580 0 : SwPosition* pDstPos = 0;
581 0 : if( this == pDestShell )
582 : {
583 : // same shell? Then create new Crsr at the
584 : // DocumentPosition passed
585 0 : pDstPos = new SwPosition( *GetCrsr()->GetPoint() );
586 0 : Point aPt( rInsPt );
587 0 : GetLayout()->GetCrsrOfst( pDstPos, aPt );
588 0 : if( !pDstPos->nNode.GetNode().IsNoTxtNode() )
589 0 : bRet = true;
590 : }
591 0 : else if( !pDestShell->GetCrsr()->GetNode().IsNoTxtNode() )
592 : {
593 0 : pDstPos = new SwPosition( *pDestShell->GetCrsr()->GetPoint() );
594 0 : bRet = true;
595 : }
596 :
597 0 : if( bRet )
598 : {
599 0 : if( GetDoc() == pDestShell->GetDoc() )
600 0 : ParkTblCrsr();
601 :
602 : bRet = pDestShell->GetDoc()->InsCopyOfTbl( *pDstPos, aBoxes,0,
603 0 : bIsMove && this == pDestShell &&
604 0 : aBoxes.size() == pTblNd->GetTable().
605 0 : GetTabSortBoxes().size(),
606 0 : this != pDestShell );
607 :
608 0 : if( this != pDestShell )
609 0 : *pDestShell->GetCrsr()->GetPoint() = *pDstPos;
610 :
611 : // create all parked Crsr?
612 0 : if( GetDoc() == pDestShell->GetDoc() )
613 0 : GetCrsr();
614 :
615 : // JP 16.04.99: Bug 64908 - Set InsPos, to assure the parked
616 : // Cursor is positioned at the insert position
617 0 : if( this == pDestShell )
618 0 : GetCrsrDocPos() = rInsPt;
619 : }
620 0 : delete pDstPos;
621 0 : }
622 : }
623 : else
624 : {
625 0 : bRet = true;
626 0 : if( this == pDestShell )
627 : {
628 : // same shell? then request the position
629 : // at the passed document position
630 0 : SwPosition aPos( *GetCrsr()->GetPoint() );
631 0 : Point aPt( rInsPt );
632 0 : GetLayout()->GetCrsrOfst( &aPos, aPt );
633 0 : bRet = !aPos.nNode.GetNode().IsNoTxtNode();
634 : }
635 0 : else if( pDestShell->GetCrsr()->GetNode().IsNoTxtNode() )
636 0 : bRet = false;
637 :
638 0 : if( bRet )
639 0 : bRet = 0 != SwEditShell::Copy( pDestShell );
640 : }
641 :
642 0 : pDestShell->GetDoc()->getIDocumentRedlineAccess().SetRedlineMode_intern( eOldRedlMode );
643 0 : mpDoc->SetCopyIsMove( bCopyIsMove );
644 :
645 : // have new table formules been inserted?
646 0 : if( pTblFldTyp->GetDepends() )
647 : {
648 : // finish old actions: the table frames are created and
649 : // a selection can be made
650 : sal_uInt16 nActCnt;
651 0 : for( nActCnt = 0; pDestShell->ActionPend(); ++nActCnt )
652 0 : pDestShell->EndAllAction();
653 :
654 0 : for( ; nActCnt; --nActCnt )
655 0 : pDestShell->StartAllAction();
656 : }
657 0 : pDestShell->GetDoc()->getIDocumentFieldsAccess().UnlockExpFlds();
658 0 : pDestShell->GetDoc()->getIDocumentFieldsAccess().UpdateFlds(NULL, false);
659 :
660 0 : pDestShell->EndAllAction();
661 0 : return bRet;
662 : }
663 :
664 : // Paste for the interal clipboard. Copy the content of the clipboard
665 : // in the document
666 : namespace {
667 : typedef boost::shared_ptr<SwPaM> PaMPtr;
668 : typedef boost::shared_ptr<SwPosition> PositionPtr;
669 : typedef std::pair< PaMPtr, PositionPtr > Insertion;
670 : }
671 :
672 4 : bool SwFEShell::Paste( SwDoc* pClpDoc, bool bIncludingPageFrames )
673 : {
674 4 : SET_CURR_SHELL( this );
675 : OSL_ENSURE( pClpDoc, "no clipboard document" );
676 4 : const sal_uInt16 nStartPageNumber = GetPhyPageNum();
677 : // then till end of the nodes array
678 8 : SwNodeIndex aIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 );
679 8 : SwPaM aCpyPam( aIdx ); //DocStart
680 :
681 : // If there are table formulas in the area, then display the table first
682 : // so that the table formula can calculate a new value first
683 : // (individual boxes in the area are retrieved via the layout)
684 4 : SwFieldType* pTblFldTyp = GetDoc()->getIDocumentFieldsAccess().GetSysFldType( RES_TABLEFLD );
685 :
686 4 : SwTableNode *pDestNd, *pSrcNd = aCpyPam.GetNode().GetTableNode();
687 4 : if( !pSrcNd ) // TabellenNode ?
688 : { // nicht ueberspringen!!
689 4 : SwCntntNode* pCNd = aCpyPam.GetNode().GetCntntNode();
690 4 : if( pCNd )
691 4 : aCpyPam.GetPoint()->nContent.Assign( pCNd, 0 );
692 0 : else if( !aCpyPam.Move( fnMoveForward, fnGoNode ))
693 0 : aCpyPam.Move( fnMoveBackward, fnGoNode );
694 : }
695 :
696 4 : aCpyPam.SetMark();
697 4 : aCpyPam.Move( fnMoveForward, fnGoDoc );
698 :
699 4 : bool bRet = true, bDelTbl = true;
700 4 : StartAllAction();
701 4 : GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_INSGLOSSARY, NULL );
702 4 : GetDoc()->getIDocumentFieldsAccess().LockExpFlds();
703 :
704 : // When the clipboard content has been created by a rectangular selection
705 : // the pasting is more sophisticated:
706 : // every paragraph will be inserted into another position.
707 : // The first positions are given by the actual cursor ring,
708 : // if there are more text portions to insert than cursor in this ring,
709 : // the additional insert positions will be created by moving the last
710 : // cursor position into the next line (like pressing the cursor down key)
711 4 : if( pClpDoc->IsColumnSelection() && !IsTableMode() )
712 : {
713 : // Creation of the list of insert positions
714 0 : std::list< Insertion > aCopyList;
715 : // The number of text portions of the rectangular selection
716 0 : const sal_uInt32 nSelCount = aCpyPam.GetPoint()->nNode.GetIndex()
717 0 : - aCpyPam.GetMark()->nNode.GetIndex();
718 0 : sal_uInt32 nCount = nSelCount;
719 0 : SwNodeIndex aClpIdx( aIdx );
720 0 : SwPaM* pStartCursor = GetCrsr();
721 0 : SwPaM* pCurrCrsr = pStartCursor;
722 0 : sal_uInt32 nCursorCount = pStartCursor->numberOf();
723 : // If the target selection is a multi-selection, often the last and first
724 : // cursor of the ring points to identical document positions. Then
725 : // we should avoid double insertion of text portions...
726 0 : while( nCursorCount > 1 && *pCurrCrsr->GetPoint() ==
727 0 : *(static_cast<SwPaM*>(pCurrCrsr->GetPrev())->GetPoint()) )
728 : {
729 0 : --nCursorCount;
730 0 : pCurrCrsr = static_cast<SwPaM*>(pCurrCrsr->GetNext());
731 0 : pStartCursor = pCurrCrsr;
732 : }
733 0 : SwPosition aStartPos( *pStartCursor->GetPoint() );
734 0 : SwPosition aInsertPos( aStartPos ); // first insertion position
735 0 : bool bCompletePara = false;
736 0 : sal_uInt16 nMove = 0;
737 0 : while( nCount )
738 : {
739 0 : --nCount;
740 : OSL_ENSURE( aIdx.GetNode().GetCntntNode(), "Who filled the clipboard?!" );
741 0 : if( aIdx.GetNode().GetCntntNode() ) // robust
742 : {
743 0 : Insertion aInsertion( PaMPtr( new SwPaM( aIdx ) ),
744 0 : PositionPtr( new SwPosition( aInsertPos ) ) );
745 0 : ++aIdx;
746 0 : aInsertion.first->SetMark();
747 0 : if( pStartCursor == pCurrCrsr->GetNext() )
748 : { // Now we have to look for insertion positions...
749 0 : if( !nMove ) // Annotate the last given insert position
750 0 : aStartPos = aInsertPos;
751 0 : SwCursor aCrsr( aStartPos, 0, false);
752 : // Check if we find another insert position by moving
753 : // down the last given position
754 0 : if( aCrsr.UpDown( false, ++nMove, 0, 0 ) )
755 0 : aInsertPos = *aCrsr.GetPoint();
756 : else // if there is no paragraph we have to create it
757 0 : bCompletePara = nCount > 0;
758 0 : nCursorCount = 0;
759 : }
760 : else // as long as we find more insert positions in the cursor ring
761 : { // we'll take them
762 0 : pCurrCrsr = static_cast<SwPaM*>(pCurrCrsr->GetNext());
763 0 : aInsertPos = *pCurrCrsr->GetPoint();
764 0 : --nCursorCount;
765 : }
766 : // If there are no more paragraphs e.g. at the end of a document,
767 : // we insert complete paragraphs instead of text portions
768 0 : if( bCompletePara )
769 0 : aInsertion.first->GetPoint()->nNode = aIdx;
770 : else
771 0 : aInsertion.first->GetPoint()->nContent =
772 0 : aInsertion.first->GetCntntNode()->Len();
773 0 : aCopyList.push_back( aInsertion );
774 : }
775 : // If there are no text portions left but there are some more
776 : // cursor positions to fill we have to restart with the first
777 : // text portion
778 0 : if( !nCount && nCursorCount )
779 : {
780 0 : nCount = std::min( nSelCount, nCursorCount );
781 0 : aIdx = aClpIdx; // Start of clipboard content
782 : }
783 : }
784 0 : std::list< Insertion >::const_iterator pCurr = aCopyList.begin();
785 0 : std::list< Insertion >::const_iterator pEnd = aCopyList.end();
786 0 : while( pCurr != pEnd )
787 : {
788 0 : SwPosition& rInsPos = *pCurr->second;
789 0 : SwPaM& rCopy = *pCurr->first;
790 0 : const SwStartNode* pBoxNd = rInsPos.nNode.GetNode().FindTableBoxStartNode();
791 0 : if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() - pBoxNd->GetIndex() &&
792 0 : rCopy.GetPoint()->nNode != rCopy.GetMark()->nNode )
793 : {
794 : // if more than one node will be copied into a cell
795 : // the box attributes have to be removed
796 0 : GetDoc()->ClearBoxNumAttrs( rInsPos.nNode );
797 : }
798 : {
799 0 : SwNodeIndex aIndexBefore(rInsPos.nNode);
800 0 : aIndexBefore--;
801 0 : pClpDoc->getIDocumentContentOperations().CopyRange( rCopy, rInsPos, false );
802 : {
803 0 : ++aIndexBefore;
804 : SwPaM aPaM(SwPosition(aIndexBefore),
805 0 : SwPosition(rInsPos.nNode));
806 0 : aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
807 0 : }
808 : }
809 0 : SaveTblBoxCntnt( &rInsPos );
810 0 : ++pCurr;
811 0 : }
812 : }
813 : else
814 : {
815 8 : FOREACHPAM_START(GetCrsr())
816 :
817 4 : if( pSrcNd &&
818 0 : 0 != ( pDestNd = GetDoc()->IsIdxInTbl( PCURCRSR->GetPoint()->nNode )))
819 : {
820 0 : SwPosition aDestPos( *PCURCRSR->GetPoint() );
821 :
822 0 : bool bParkTblCrsr = false;
823 0 : const SwStartNode* pSttNd = PCURCRSR->GetNode().FindTableBoxStartNode();
824 :
825 : // TABLE IN TABLE: copy table in table
826 : // search boxes via the layout
827 0 : SwSelBoxes aBoxes;
828 0 : if( IsTableMode() ) // table selection?
829 : {
830 0 : GetTblSel( *this, aBoxes );
831 0 : ParkTblCrsr();
832 0 : bParkTblCrsr = true;
833 : }
834 0 : else if( !PCURCRSR->HasMark() && PCURCRSR->GetNext() == PCURCRSR &&
835 0 : ( !pSrcNd->GetTable().IsTblComplex() ||
836 0 : pDestNd->GetTable().IsNewModel() ) )
837 : {
838 : // make relative table copy
839 0 : SwTableBox* pBox = pDestNd->GetTable().GetTblBox(
840 0 : pSttNd->GetIndex() );
841 : OSL_ENSURE( pBox, "Box steht nicht in dieser Tabelle" );
842 0 : aBoxes.insert( pBox );
843 : }
844 :
845 0 : SwNodeIndex aNdIdx( *pDestNd->EndOfSectionNode());
846 0 : if( !bParkTblCrsr )
847 : {
848 : // exit first the complete table
849 : // ???? what about only table in a frame ?????
850 0 : SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx );
851 0 : SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 ));
852 : // #i59539: Don't remove all redline
853 0 : SwPaM const tmpPaM(*pDestNd, *pDestNd->EndOfSectionNode());
854 0 : ::PaMCorrAbs(tmpPaM, aPos);
855 : }
856 :
857 0 : bRet = GetDoc()->InsCopyOfTbl( aDestPos, aBoxes, &pSrcNd->GetTable(),
858 0 : false, false );
859 :
860 0 : if( bParkTblCrsr )
861 0 : GetCrsr();
862 : else
863 : {
864 : // return to the box
865 0 : aNdIdx = *pSttNd;
866 0 : SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx );
867 0 : SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 ));
868 : // #i59539: Don't remove all redline
869 0 : SwNode & rNode(PCURCRSR->GetPoint()->nNode.GetNode());
870 0 : SwCntntNode *const pCntntNode( rNode.GetCntntNode() );
871 : SwPaM const tmpPam(rNode, 0,
872 0 : rNode, (pCntntNode) ? pCntntNode->Len() : 0);
873 0 : ::PaMCorrAbs(tmpPam, aPos);
874 : }
875 :
876 0 : break; // exit the "while-loop"
877 : }
878 6 : else if( *aCpyPam.GetPoint() == *aCpyPam.GetMark() &&
879 2 : pClpDoc->GetSpzFrmFmts()->size() )
880 : {
881 : // we need a DrawView
882 2 : if( !Imp()->GetDrawView() )
883 0 : MakeDrawView();
884 :
885 2 : std::set<const SwFrmFmt*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pClpDoc);
886 6 : for ( sal_uInt16 i = 0; i < pClpDoc->GetSpzFrmFmts()->size(); ++i )
887 : {
888 4 : bool bInsWithFmt = true;
889 4 : const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i];
890 :
891 8 : if( Imp()->GetDrawView()->IsGroupEntered() &&
892 4 : RES_DRAWFRMFMT == rCpyFmt.Which() &&
893 0 : (FLY_AS_CHAR != rCpyFmt.GetAnchor().GetAnchorId()) )
894 : {
895 0 : const SdrObject* pSdrObj = rCpyFmt.FindSdrObject();
896 0 : if( pSdrObj )
897 : {
898 : SdrObject* pNew = GetDoc()->CloneSdrObj( *pSdrObj,
899 0 : false, false );
900 :
901 : // Insert object sets any anchor position to 0.
902 : // Therefore we calculate the absolute position here
903 : // and after the insert the anchor of the object
904 : // is set to the anchor of the group object.
905 0 : Rectangle aSnapRect = pNew->GetSnapRect();
906 0 : if( pNew->GetAnchorPos().X() || pNew->GetAnchorPos().Y() )
907 : {
908 0 : const Point aPoint( 0, 0 );
909 : // OD 2004-04-05 #i26791# - direct drawing object
910 : // positioning for group members
911 0 : pNew->NbcSetAnchorPos( aPoint );
912 0 : pNew->NbcSetSnapRect( aSnapRect );
913 : }
914 :
915 0 : Imp()->GetDrawView()->InsertObjectAtView( pNew, *Imp()->GetPageView() );
916 :
917 0 : Point aGrpAnchor( 0, 0 );
918 0 : SdrObjList* pList = pNew->GetObjList();
919 0 : if ( pList )
920 : {
921 0 : SdrObject* pOwner = pList->GetOwnerObj();
922 0 : if ( pOwner )
923 : {
924 0 : SdrObjGroup* pThisGroup = PTR_CAST(SdrObjGroup, pOwner);
925 0 : aGrpAnchor = pThisGroup->GetAnchorPos();
926 : }
927 : }
928 :
929 : // OD 2004-04-05 #i26791# - direct drawing object
930 : // positioning for group members
931 0 : pNew->NbcSetAnchorPos( aGrpAnchor );
932 0 : pNew->SetSnapRect( aSnapRect );
933 :
934 0 : bInsWithFmt = false;
935 : }
936 : }
937 :
938 4 : if( bInsWithFmt )
939 : {
940 4 : SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
941 8 : if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
942 4 : (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
943 0 : (FLY_AS_CHAR == aAnchor.GetAnchorId()))
944 : {
945 4 : SwPosition* pPos = PCURCRSR->GetPoint();
946 : // allow shapes (no controls) in header/footer
947 6 : if( RES_DRAWFRMFMT == rCpyFmt.Which() &&
948 2 : GetDoc()->IsInHeaderFooter( pPos->nNode ) )
949 : {
950 0 : const SdrObject *pCpyObj = rCpyFmt.FindSdrObject();
951 0 : if (pCpyObj && CheckControlLayer(pCpyObj))
952 0 : continue;
953 : }
954 :
955 : // Ignore TextBoxes, they are already handled in sw::DocumentLayoutManager::CopyLayoutFmt().
956 4 : if (aTextBoxes.find(&rCpyFmt) != aTextBoxes.end())
957 2 : continue;
958 :
959 2 : aAnchor.SetAnchor( pPos );
960 : }
961 0 : else if ( FLY_AT_PAGE == aAnchor.GetAnchorId() )
962 : {
963 0 : aAnchor.SetPageNum( GetPhyPageNum() );
964 : }
965 0 : else if( FLY_AT_FLY == aAnchor.GetAnchorId() )
966 : {
967 0 : Point aPt;
968 0 : lcl_SetAnchor( *PCURCRSR->GetPoint(), PCURCRSR->GetNode(),
969 0 : 0, aPt, *this, aAnchor, aPt, false );
970 : }
971 :
972 2 : SwFrmFmt * pNew = GetDoc()->getIDocumentLayoutAccess().CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
973 :
974 2 : if( pNew )
975 : {
976 2 : if( RES_FLYFRMFMT == pNew->Which() )
977 : {
978 0 : const Point aPt( GetCrsrDocPos() );
979 : SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pNew)->
980 0 : GetFrm( &aPt, false );
981 0 : if( pFlyFrm )
982 0 : SelectFlyFrm( *pFlyFrm, true );
983 : // always pick the first FlyFrame only; the others
984 : // were copied to the clipboard via Fly in Fly
985 0 : break;
986 : }
987 : else
988 : {
989 : OSL_ENSURE( RES_DRAWFRMFMT == pNew->Which(), "Neues Format.");
990 : // #i52780# - drawing object has
991 : // to be made visible on paste.
992 : {
993 : SwDrawContact* pContact =
994 2 : static_cast<SwDrawContact*>(pNew->FindContactObj());
995 2 : pContact->MoveObjToVisibleLayer( pContact->GetMaster() );
996 : }
997 2 : SdrObject *pObj = pNew->FindSdrObject();
998 2 : SwDrawView *pDV = Imp()->GetDrawView();
999 2 : pDV->MarkObj( pObj, pDV->GetSdrPageView() );
1000 : // #i47455# - notify draw frame format
1001 : // that position attributes are already set.
1002 2 : if ( pNew->ISA(SwDrawFrmFmt) )
1003 : {
1004 2 : static_cast<SwDrawFrmFmt*>(pNew)->PosAttrSet();
1005 : }
1006 : }
1007 2 : }
1008 : }
1009 2 : }
1010 : }
1011 : else
1012 : {
1013 2 : if( bDelTbl && IsTableMode() )
1014 : {
1015 0 : SwEditShell::Delete();
1016 0 : bDelTbl = false;
1017 : }
1018 :
1019 2 : SwPosition& rInsPos = *PCURCRSR->GetPoint();
1020 2 : const SwStartNode* pBoxNd = rInsPos.nNode.GetNode().
1021 2 : FindTableBoxStartNode();
1022 2 : if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() -
1023 2 : pBoxNd->GetIndex() &&
1024 0 : aCpyPam.GetPoint()->nNode != aCpyPam.GetMark()->nNode )
1025 : {
1026 : // Copy more than 1 node in the current box. But
1027 : // then the BoxAttribute should be removed
1028 0 : GetDoc()->ClearBoxNumAttrs( rInsPos.nNode );
1029 : }
1030 :
1031 : // **
1032 : // ** Update SwDoc::Append, if you change the following code **
1033 : // **
1034 :
1035 : // find out if the clipboard document starts with a table
1036 2 : bool bStartWithTable = 0 != aCpyPam.Start()->nNode.GetNode().FindTableNode();
1037 2 : SwPosition aInsertPosition( rInsPos );
1038 :
1039 : {
1040 2 : SwNodeIndex aIndexBefore(rInsPos.nNode);
1041 :
1042 2 : aIndexBefore--;
1043 :
1044 2 : pClpDoc->getIDocumentContentOperations().CopyRange( aCpyPam, rInsPos, false );
1045 : // Note: aCpyPam is invalid now
1046 :
1047 2 : ++aIndexBefore;
1048 : SwPaM aPaM(SwPosition(aIndexBefore),
1049 4 : SwPosition(rInsPos.nNode));
1050 :
1051 2 : aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
1052 :
1053 : // Update the rsid of each pasted text node.
1054 2 : SwNodes &rDestNodes = GetDoc()->GetNodes();
1055 2 : sal_uLong const nEndIdx = aPaM.End()->nNode.GetIndex();
1056 :
1057 36 : for (sal_uLong nIdx = aPaM.Start()->nNode.GetIndex();
1058 : nIdx <= nEndIdx; ++nIdx)
1059 : {
1060 34 : SwTxtNode *const pTxtNode = rDestNodes[nIdx]->GetTxtNode();
1061 34 : if ( pTxtNode )
1062 : {
1063 14 : GetDoc()->UpdateParRsid( pTxtNode );
1064 : }
1065 2 : }
1066 : }
1067 :
1068 2 : SaveTblBoxCntnt( &rInsPos );
1069 2 : if(bIncludingPageFrames && bStartWithTable)
1070 : {
1071 : //remove the paragraph in front of the table
1072 0 : SwPaM aPara(aInsertPosition);
1073 0 : GetDoc()->getIDocumentContentOperations().DelFullPara(aPara);
1074 : }
1075 : //additionally copy page bound frames
1076 2 : if( bIncludingPageFrames && pClpDoc->GetSpzFrmFmts()->size() )
1077 : {
1078 : // create a draw view if necessary
1079 0 : if( !Imp()->GetDrawView() )
1080 0 : MakeDrawView();
1081 :
1082 0 : for ( sal_uInt16 i = 0; i < pClpDoc->GetSpzFrmFmts()->size(); ++i )
1083 : {
1084 0 : const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i];
1085 0 : SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
1086 0 : if ( FLY_AT_PAGE != aAnchor.GetAnchorId() )
1087 0 : continue;
1088 0 : aAnchor.SetPageNum( aAnchor.GetPageNum() + nStartPageNumber - 1 );
1089 0 : GetDoc()->getIDocumentLayoutAccess().CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
1090 0 : }
1091 2 : }
1092 : }
1093 :
1094 4 : FOREACHPAM_END()
1095 : }
1096 :
1097 4 : GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_INSGLOSSARY, NULL );
1098 :
1099 : // have new table formulas been inserted?
1100 4 : if( pTblFldTyp->GetDepends() )
1101 : {
1102 : // finish old action: table-frames have been created
1103 : // a selection can be made now
1104 : sal_uInt16 nActCnt;
1105 0 : for( nActCnt = 0; ActionPend(); ++nActCnt )
1106 0 : EndAllAction();
1107 :
1108 0 : for( ; nActCnt; --nActCnt )
1109 0 : StartAllAction();
1110 : }
1111 4 : GetDoc()->getIDocumentFieldsAccess().UnlockExpFlds();
1112 4 : GetDoc()->getIDocumentFieldsAccess().UpdateFlds(NULL, false);
1113 4 : EndAllAction();
1114 :
1115 8 : return bRet;
1116 : }
1117 :
1118 0 : bool SwFEShell::PastePages( SwFEShell& rToFill, sal_uInt16 nStartPage, sal_uInt16 nEndPage)
1119 : {
1120 0 : Push();
1121 0 : if(!GotoPage(nStartPage))
1122 : {
1123 0 : Pop(false);
1124 0 : return false;
1125 : }
1126 0 : MovePage( fnPageCurr, fnPageStart );
1127 0 : SwPaM aCpyPam( *GetCrsr()->GetPoint() );
1128 0 : OUString sStartingPageDesc = GetPageDesc( GetCurPageDesc()).GetName();
1129 0 : SwPageDesc* pDesc = rToFill.FindPageDescByName( sStartingPageDesc, true );
1130 0 : if( pDesc )
1131 0 : rToFill.ChgCurPageDesc( *pDesc );
1132 :
1133 0 : if(!GotoPage(nEndPage))
1134 : {
1135 0 : Pop(false);
1136 0 : return false;
1137 : }
1138 : //if the page starts with a table a paragraph has to be inserted before
1139 0 : SwNode* pTableNode = aCpyPam.GetNode().FindTableNode();
1140 0 : if(pTableNode)
1141 : {
1142 : //insert a paragraph
1143 0 : StartUndo(UNDO_INSERT);
1144 0 : SwNodeIndex aTblIdx( *pTableNode, -1 );
1145 0 : SwPosition aBefore(aTblIdx);
1146 0 : if(GetDoc()->getIDocumentContentOperations().AppendTxtNode( aBefore ))
1147 : {
1148 0 : SwPaM aTmp(aBefore);
1149 0 : aCpyPam = aTmp;
1150 : }
1151 0 : EndUndo(UNDO_INSERT);
1152 : }
1153 :
1154 0 : MovePage( fnPageCurr, fnPageEnd );
1155 0 : aCpyPam.SetMark();
1156 0 : *aCpyPam.GetMark() = *GetCrsr()->GetPoint();
1157 :
1158 0 : SET_CURR_SHELL( this );
1159 :
1160 0 : StartAllAction();
1161 0 : GetDoc()->getIDocumentFieldsAccess().LockExpFlds();
1162 0 : SetSelection(aCpyPam);
1163 : // copy the text of the selection
1164 0 : SwEditShell::Copy(&rToFill);
1165 :
1166 0 : if(pTableNode)
1167 : {
1168 : //remove the inserted paragraph
1169 0 : Undo();
1170 : //remove the paragraph in the second doc, too
1171 0 : SwNodeIndex aIdx( rToFill.GetDoc()->GetNodes().GetEndOfExtras(), 2 );
1172 0 : SwPaM aPara( aIdx ); //DocStart
1173 0 : rToFill.GetDoc()->getIDocumentContentOperations().DelFullPara(aPara);
1174 : }
1175 : // now the page bound objects
1176 : // additionally copy page bound frames
1177 0 : if( GetDoc()->GetSpzFrmFmts()->size() )
1178 : {
1179 : // create a draw view if necessary
1180 0 : if( !rToFill.Imp()->GetDrawView() )
1181 0 : rToFill.MakeDrawView();
1182 :
1183 0 : for ( sal_uInt16 i = 0; i < GetDoc()->GetSpzFrmFmts()->size(); ++i )
1184 : {
1185 0 : const SwFrmFmt& rCpyFmt = *(*GetDoc()->GetSpzFrmFmts())[i];
1186 0 : SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
1187 0 : if ((FLY_AT_PAGE == aAnchor.GetAnchorId()) &&
1188 0 : aAnchor.GetPageNum() >= nStartPage && aAnchor.GetPageNum() <= nEndPage)
1189 : {
1190 0 : aAnchor.SetPageNum( aAnchor.GetPageNum() - nStartPage + 1);
1191 : }
1192 : else
1193 0 : continue;
1194 0 : rToFill.GetDoc()->getIDocumentLayoutAccess().CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
1195 0 : }
1196 : }
1197 0 : GetDoc()->getIDocumentFieldsAccess().UnlockExpFlds();
1198 0 : GetDoc()->getIDocumentFieldsAccess().UpdateFlds(NULL, false);
1199 0 : Pop(false);
1200 0 : EndAllAction();
1201 :
1202 0 : return true;
1203 : }
1204 :
1205 0 : bool SwFEShell::GetDrawObjGraphic( sal_uLong nFmt, Graphic& rGrf ) const
1206 : {
1207 : OSL_ENSURE( Imp()->HasDrawView(), "GetDrawObjGraphic without DrawView?" );
1208 0 : const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1209 0 : bool bConvert = true;
1210 0 : if( rMrkList.GetMarkCount() )
1211 : {
1212 0 : if( rMrkList.GetMarkCount() == 1 &&
1213 0 : rMrkList.GetMark( 0 )->GetMarkedSdrObj()->ISA(SwVirtFlyDrawObj) )
1214 : {
1215 : // select frame
1216 0 : if( CNT_GRF == GetCntType() )
1217 : {
1218 0 : const Graphic* pGrf( GetGraphic() );
1219 0 : if ( pGrf )
1220 : {
1221 0 : Graphic aGrf( *pGrf );
1222 0 : if( SOT_FORMAT_GDIMETAFILE == nFmt )
1223 : {
1224 0 : if( GRAPHIC_BITMAP != aGrf.GetType() )
1225 : {
1226 0 : rGrf = aGrf;
1227 0 : bConvert = false;
1228 : }
1229 0 : else if( GetWin() )
1230 : {
1231 0 : Size aSz;
1232 0 : Point aPt;
1233 0 : GetGrfSize( aSz );
1234 :
1235 0 : VirtualDevice aVirtDev;
1236 0 : aVirtDev.EnableOutput( false );
1237 :
1238 0 : MapMode aTmp( GetWin()->GetMapMode() );
1239 0 : aTmp.SetOrigin( aPt );
1240 0 : aVirtDev.SetMapMode( aTmp );
1241 :
1242 0 : GDIMetaFile aMtf;
1243 0 : aMtf.Record( &aVirtDev );
1244 0 : aGrf.Draw( &aVirtDev, aPt, aSz );
1245 0 : aMtf.Stop();
1246 0 : aMtf.SetPrefMapMode( aTmp );
1247 0 : aMtf.SetPrefSize( aSz );
1248 0 : rGrf = aMtf;
1249 : }
1250 : }
1251 0 : else if( GRAPHIC_BITMAP == aGrf.GetType() )
1252 : {
1253 0 : rGrf = aGrf;
1254 0 : bConvert = false;
1255 : }
1256 : else
1257 : {
1258 : // fix(23806): not the origial size, but the current one.
1259 : // Otherwise it could happen that for vector graphics
1260 : // many MB's of memory are allocated.
1261 0 : const Size aSz( FindFlyFrm()->Prt().SSize() );
1262 0 : VirtualDevice aVirtDev( *GetWin() );
1263 :
1264 0 : MapMode aTmp( MAP_TWIP );
1265 0 : aVirtDev.SetMapMode( aTmp );
1266 0 : if( aVirtDev.SetOutputSize( aSz ) )
1267 : {
1268 0 : aGrf.Draw( &aVirtDev, Point(), aSz );
1269 0 : rGrf = aVirtDev.GetBitmap( Point(), aSz );
1270 : }
1271 : else
1272 : {
1273 0 : rGrf = aGrf;
1274 0 : bConvert = false;
1275 0 : }
1276 0 : }
1277 : }
1278 : }
1279 : }
1280 0 : else if( SOT_FORMAT_GDIMETAFILE == nFmt )
1281 0 : rGrf = Imp()->GetDrawView()->GetMarkedObjMetaFile();
1282 0 : else if( SOT_FORMAT_BITMAP == nFmt || SOT_FORMATSTR_ID_PNG == nFmt )
1283 0 : rGrf = Imp()->GetDrawView()->GetMarkedObjBitmapEx();
1284 : }
1285 0 : return bConvert;
1286 : }
1287 :
1288 : // #i50824#
1289 : // replace method <lcl_RemoveOleObjsFromSdrModel> by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs>
1290 0 : static void lcl_ConvertSdrOle2ObjsToSdrGrafObjs( SdrModel* _pModel )
1291 : {
1292 0 : for ( sal_uInt16 nPgNum = 0; nPgNum < _pModel->GetPageCount(); ++nPgNum )
1293 : {
1294 : // setup object iterator in order to iterate through all objects
1295 : // including objects in group objects, but exclusive group objects.
1296 0 : SdrObjListIter aIter(*(_pModel->GetPage( nPgNum )));
1297 0 : while( aIter.IsMore() )
1298 : {
1299 0 : SdrOle2Obj* pOle2Obj = dynamic_cast< SdrOle2Obj* >( aIter.Next() );
1300 0 : if( pOle2Obj )
1301 : {
1302 : // found an ole2 shape
1303 0 : SdrObjList* pObjList = pOle2Obj->GetObjList();
1304 :
1305 : // get its graphic
1306 0 : Graphic aGraphic;
1307 0 : pOle2Obj->Connect();
1308 0 : const Graphic* pGraphic = pOle2Obj->GetGraphic();
1309 0 : if( pGraphic )
1310 0 : aGraphic = *pGraphic;
1311 0 : pOle2Obj->Disconnect();
1312 :
1313 : // create new graphic shape with the ole graphic and shape size
1314 0 : SdrGrafObj* pGraphicObj = new SdrGrafObj( aGraphic, pOle2Obj->GetCurrentBoundRect() );
1315 : // apply layer of ole2 shape at graphic shape
1316 0 : pGraphicObj->SetLayer( pOle2Obj->GetLayer() );
1317 :
1318 : // replace ole2 shape with the new graphic object and delete the ol2 shape
1319 0 : SdrObject* pRemovedObject = pObjList->ReplaceObject( pGraphicObj, pOle2Obj->GetOrdNum() );
1320 0 : SdrObject::Free( pRemovedObject );
1321 : }
1322 : }
1323 0 : }
1324 0 : }
1325 :
1326 0 : void SwFEShell::Paste( SvStream& rStrm, sal_uInt16 nAction, const Point* pPt )
1327 : {
1328 0 : SET_CURR_SHELL( this );
1329 0 : StartAllAction();
1330 0 : StartUndo();
1331 :
1332 0 : SvtPathOptions aPathOpt;
1333 : FmFormModel* pModel = new FmFormModel( aPathOpt.GetPalettePath(),
1334 0 : 0, GetDoc()->GetDocShell() );
1335 0 : pModel->GetItemPool().FreezeIdRanges();
1336 :
1337 0 : rStrm.Seek(0);
1338 :
1339 0 : uno::Reference< io::XInputStream > xInputStream( new utl::OInputStreamWrapper( rStrm ) );
1340 0 : SvxDrawingLayerImport( pModel, xInputStream );
1341 :
1342 0 : if ( !Imp()->HasDrawView() )
1343 0 : Imp()->MakeDrawView();
1344 :
1345 0 : Point aPos( pPt ? *pPt : GetCharRect().Pos() );
1346 0 : SdrView *pView = Imp()->GetDrawView();
1347 :
1348 : // drop on the existing object: replace object or apply new attributes
1349 0 : if( pModel->GetPageCount() > 0 &&
1350 0 : 1 == pModel->GetPage(0)->GetObjCount() &&
1351 0 : 1 == pView->GetMarkedObjectList().GetMarkCount() )
1352 : {
1353 : // replace a marked 'virtual' drawing object
1354 : // by its corresponding 'master' drawing object in the mark list.
1355 0 : SwDrawView::ReplaceMarkedDrawVirtObjs( *pView );
1356 :
1357 0 : SdrObject* pClpObj = pModel->GetPage(0)->GetObj(0);
1358 0 : SdrObject* pOldObj = pView->GetMarkedObjectList().GetMark( 0 )->GetMarkedSdrObj();
1359 :
1360 0 : if( SW_PASTESDR_SETATTR == nAction && pOldObj->ISA(SwVirtFlyDrawObj) )
1361 0 : nAction = SW_PASTESDR_REPLACE;
1362 :
1363 0 : switch( nAction )
1364 : {
1365 : case SW_PASTESDR_REPLACE:
1366 : {
1367 0 : const SwFrmFmt* pFmt(0);
1368 0 : const SwFrm* pAnchor(0);
1369 0 : if( pOldObj->ISA(SwVirtFlyDrawObj) )
1370 : {
1371 0 : pFmt = FindFrmFmt( pOldObj );
1372 :
1373 0 : Point aNullPt;
1374 0 : SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFmt)->GetFrm( &aNullPt );
1375 0 : pAnchor = pFlyFrm ? pFlyFrm->GetAnchorFrm() : NULL;
1376 :
1377 0 : if (!pAnchor || pAnchor->FindFooterOrHeader())
1378 : {
1379 : // if there is a textframe in the header/footer:
1380 : // do not replace but insert
1381 0 : nAction = SW_PASTESDR_INSERT;
1382 0 : break;
1383 : }
1384 : }
1385 :
1386 0 : SdrObject* pNewObj = pClpObj->Clone();
1387 0 : Rectangle aOldObjRect( pOldObj->GetCurrentBoundRect() );
1388 0 : Size aOldObjSize( aOldObjRect.GetSize() );
1389 0 : Rectangle aNewRect( pNewObj->GetCurrentBoundRect() );
1390 0 : Size aNewSize( aNewRect.GetSize() );
1391 :
1392 0 : Fraction aScaleWidth( aOldObjSize.Width(), aNewSize.Width() );
1393 0 : Fraction aScaleHeight( aOldObjSize.Height(), aNewSize.Height());
1394 0 : pNewObj->NbcResize( aNewRect.TopLeft(), aScaleWidth, aScaleHeight);
1395 :
1396 0 : Point aVec = aOldObjRect.TopLeft() - aNewRect.TopLeft();
1397 0 : pNewObj->NbcMove(Size(aVec.getX(), aVec.getY()));
1398 :
1399 0 : if( pNewObj->ISA( SdrUnoObj ) )
1400 0 : pNewObj->SetLayer( GetDoc()->getIDocumentDrawModelAccess().GetControlsId() );
1401 0 : else if( pOldObj->ISA( SdrUnoObj ) )
1402 0 : pNewObj->SetLayer( GetDoc()->getIDocumentDrawModelAccess().GetHeavenId() );
1403 : else
1404 0 : pNewObj->SetLayer( pOldObj->GetLayer() );
1405 :
1406 0 : if( pOldObj->ISA(SwVirtFlyDrawObj) )
1407 : {
1408 : // store attributes, then set SdrObject
1409 0 : SfxItemSet aFrmSet( mpDoc->GetAttrPool(),
1410 0 : RES_SURROUND, RES_ANCHOR );
1411 0 : aFrmSet.Set( pFmt->GetAttrSet() );
1412 :
1413 0 : Point aNullPt;
1414 0 : if( pAnchor->IsTxtFrm() && ((SwTxtFrm*)pAnchor)->IsFollow() )
1415 : {
1416 0 : const SwTxtFrm* pTmp = (SwTxtFrm*)pAnchor;
1417 0 : do {
1418 0 : pTmp = pTmp->FindMaster();
1419 : OSL_ENSURE( pTmp, "Where's my Master?" );
1420 0 : } while( pTmp->IsFollow() );
1421 0 : pAnchor = pTmp;
1422 : }
1423 0 : if( pOldObj->ISA( SdrCaptionObj ))
1424 0 : aNullPt = ((SdrCaptionObj*)pOldObj)->GetTailPos();
1425 : else
1426 0 : aNullPt = aOldObjRect.TopLeft();
1427 :
1428 0 : Point aNewAnchor = pAnchor->GetFrmAnchorPos( ::HasWrap( pOldObj ) );
1429 : // OD 2004-04-05 #i26791# - direct positioning of Writer
1430 : // fly frame object for <SwDoc::Insert(..)>
1431 0 : pNewObj->NbcSetRelativePos( aNullPt - aNewAnchor );
1432 0 : pNewObj->NbcSetAnchorPos( aNewAnchor );
1433 :
1434 0 : pOldObj->GetOrdNum();
1435 :
1436 0 : DelSelectedObj();
1437 :
1438 0 : GetDoc()->getIDocumentContentOperations().InsertDrawObj( *GetCrsr(), *pNewObj, aFrmSet );
1439 : }
1440 : else
1441 : {
1442 : // #i123922# for handling MasterObject and virtual ones correctly, SW
1443 : // wants us to call ReplaceObject at the page, but that also
1444 : // triggers the same assertion (I tried it), so stay at the view method
1445 0 : pView->ReplaceObjectAtView(pOldObj, *Imp()->GetPageView(), pNewObj);
1446 : }
1447 : }
1448 0 : break;
1449 :
1450 : case SW_PASTESDR_SETATTR:
1451 : {
1452 0 : SfxItemSet aSet( GetAttrPool() );
1453 0 : const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pClpObj);
1454 :
1455 0 : if(pSdrGrafObj)
1456 : {
1457 0 : SdrObject* pTarget = 0;
1458 :
1459 0 : if(0 != pView->GetMarkedObjectList().GetMarkCount())
1460 : {
1461 : // try to get target (if it's at least one, take first)
1462 0 : SdrMark* pMark = pView->GetMarkedObjectList().GetMark(0);
1463 :
1464 0 : if(pMark)
1465 : {
1466 0 : pTarget = pMark->GetMarkedSdrObj();
1467 : }
1468 : }
1469 :
1470 0 : if(pTarget)
1471 : {
1472 : // copy ItemSet from target
1473 0 : aSet.Set(pTarget->GetMergedItemSet());
1474 : }
1475 :
1476 : // for SdrGrafObj, use the graphic as fill style argument
1477 0 : const Graphic& rGraphic = pSdrGrafObj->GetGraphic();
1478 :
1479 0 : if(GRAPHIC_NONE != rGraphic.GetType() && GRAPHIC_DEFAULT != rGraphic.GetType())
1480 : {
1481 0 : aSet.Put(XFillBitmapItem(OUString(), rGraphic));
1482 0 : aSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP));
1483 : }
1484 : }
1485 : else
1486 : {
1487 0 : aSet.Put(pClpObj->GetMergedItemSet());
1488 : }
1489 :
1490 0 : pView->SetAttributes( aSet, false );
1491 : }
1492 0 : break;
1493 :
1494 : default:
1495 0 : nAction = SW_PASTESDR_INSERT;
1496 0 : break;
1497 : }
1498 : }
1499 : else
1500 0 : nAction = SW_PASTESDR_INSERT;
1501 :
1502 0 : if( SW_PASTESDR_INSERT == nAction )
1503 : {
1504 0 : ::sw::DrawUndoGuard drawUndoGuard(GetDoc()->GetIDocumentUndoRedo());
1505 :
1506 0 : bool bDesignMode = pView->IsDesignMode();
1507 0 : if( !bDesignMode )
1508 0 : pView->SetDesignMode( true );
1509 :
1510 : // #i50824#
1511 : // method <lcl_RemoveOleObjsFromSdrModel> replaced by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs>
1512 0 : lcl_ConvertSdrOle2ObjsToSdrGrafObjs( pModel );
1513 0 : pView->Paste(*pModel, aPos, NULL, 0, OUString(), OUString());
1514 :
1515 0 : const size_t nCnt = pView->GetMarkedObjectList().GetMarkCount();
1516 0 : if( nCnt )
1517 : {
1518 0 : const Point aNull( 0, 0 );
1519 0 : for( size_t i=0; i < nCnt; ++i )
1520 : {
1521 0 : SdrObject *pObj = pView->GetMarkedObjectList().GetMark(i)->GetMarkedSdrObj();
1522 0 : pObj->ImpSetAnchorPos( aNull );
1523 : }
1524 :
1525 0 : pView->SetCurrentObj( OBJ_GRUP, SdrInventor );
1526 0 : if ( nCnt > 1 )
1527 0 : pView->GroupMarked();
1528 0 : SdrObject *pObj = pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
1529 0 : if( pObj->ISA( SdrUnoObj ) )
1530 : {
1531 0 : pObj->SetLayer( GetDoc()->getIDocumentDrawModelAccess().GetControlsId() );
1532 0 : bDesignMode = true;
1533 : }
1534 : else
1535 0 : pObj->SetLayer( GetDoc()->getIDocumentDrawModelAccess().GetHeavenId() );
1536 0 : const Rectangle &rSnap = pObj->GetSnapRect();
1537 0 : const Size aDiff( rSnap.GetWidth()/2, rSnap.GetHeight()/2 );
1538 0 : pView->MoveMarkedObj( aDiff );
1539 0 : ImpEndCreate();
1540 0 : if( !bDesignMode )
1541 0 : pView->SetDesignMode( false );
1542 0 : }
1543 : }
1544 0 : EndUndo();
1545 0 : EndAllAction();
1546 0 : delete pModel;
1547 0 : }
1548 :
1549 0 : bool SwFEShell::Paste(const Graphic &rGrf, const OUString& rURL)
1550 : {
1551 0 : SET_CURR_SHELL( this );
1552 0 : SdrObject* pObj = 0;
1553 0 : SdrView *pView = Imp()->GetDrawView();
1554 :
1555 0 : bool bRet = 1 == pView->GetMarkedObjectList().GetMarkCount() &&
1556 0 : (pObj = pView->GetMarkedObjectList().GetMark( 0 )->GetMarkedSdrObj())->IsClosedObj() &&
1557 0 : !pObj->ISA( SdrOle2Obj );
1558 :
1559 0 : if( bRet && pObj )
1560 : {
1561 : // #i123922# added code to handle the two cases of SdrGrafObj and a fillable, non-
1562 : // OLE object in focus
1563 0 : SdrObject* pResult = pObj;
1564 :
1565 0 : if(dynamic_cast< SdrGrafObj* >(pObj))
1566 : {
1567 0 : SdrGrafObj* pNewGrafObj = (SdrGrafObj*)pObj->Clone();
1568 :
1569 0 : pNewGrafObj->SetGraphic(rGrf);
1570 :
1571 : // #i123922# for handling MasterObject and virtual ones correctly, SW
1572 : // wants us to call ReplaceObject at the page, but that also
1573 : // triggers the same assertion (I tried it), so stay at the view method
1574 0 : pView->ReplaceObjectAtView(pObj, *pView->GetSdrPageView(), pNewGrafObj);
1575 :
1576 0 : OUString aReferer;
1577 0 : SwDocShell *pDocShell = GetDoc()->GetDocShell();
1578 0 : if (pDocShell->HasName()) {
1579 0 : aReferer = pDocShell->GetMedium()->GetName();
1580 : }
1581 :
1582 : // set in all cases - the Clone() will have copied an existing link (!)
1583 0 : pNewGrafObj->SetGraphicLink(rURL, aReferer, OUString());
1584 :
1585 0 : pResult = pNewGrafObj;
1586 : }
1587 : else
1588 : {
1589 0 : pView->AddUndo(new SdrUndoAttrObj(*pObj));
1590 :
1591 0 : SfxItemSet aSet(pView->GetModel()->GetItemPool(), XATTR_FILLSTYLE, XATTR_FILLBITMAP);
1592 :
1593 0 : aSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP));
1594 0 : aSet.Put(XFillBitmapItem(OUString(), rGrf));
1595 0 : pObj->SetMergedItemSetAndBroadcast(aSet);
1596 : }
1597 :
1598 : // we are done; mark the modified/new object
1599 0 : pView->MarkObj(pResult, pView->GetSdrPageView());
1600 : }
1601 :
1602 0 : return bRet;
1603 270 : }
1604 :
1605 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|