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