Bug Summary

File:home/maarten/src/libreoffice/core/sw/source/core/frmedt/fecopy.cxx
Warning:line 1460, column 30
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

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