LibreOffice Module sc (master) 1
viewfun3.cxx
Go to the documentation of this file.
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 <scitems.hxx>
21#include <svx/svdpage.hxx>
22#include <sfx2/docfile.hxx>
24#include <comphelper/lok.hxx>
25#include <sot/formats.hxx>
26#include <sot/storage.hxx>
27#include <vcl/graph.hxx>
28#include <vcl/svapp.hxx>
29#include <vcl/weld.hxx>
30#include <tools/urlobj.hxx>
31#include <sot/exchange.hxx>
32#include <memory>
33#include <vcl/uitest/logger.hxx>
36#include <osl/diagnose.h>
37
38#include <attrib.hxx>
39#include <patattr.hxx>
40#include <dociter.hxx>
41#include <viewfunc.hxx>
42#include <tabvwsh.hxx>
43#include <docsh.hxx>
44#include <docfunc.hxx>
45#include <undoblk.hxx>
46#include <refundo.hxx>
47#include <globstr.hrc>
48#include <scresid.hxx>
49#include <global.hxx>
50#include <transobj.hxx>
51#include <drwtrans.hxx>
52#include <chgtrack.hxx>
53#include <waitoff.hxx>
54#include <scmod.hxx>
55#include <inputopt.hxx>
56#include <warnbox.hxx>
57#include <drwlayer.hxx>
58#include <editable.hxx>
59#include <docuno.hxx>
60#include <clipparam.hxx>
61#include <undodat.hxx>
62#include <drawview.hxx>
63#include <cliputil.hxx>
64#include <clipoptions.hxx>
65#include <gridwin.hxx>
66#include <com/sun/star/util/XCloneable.hpp>
67
68using namespace com::sun::star;
69
70namespace {
71
72void collectUIInformation(std::map<OUString, OUString>&& aParameters, const OUString& action)
73{
74 EventDescription aDescription;
75 aDescription.aID = "grid_window";
76 aDescription.aAction = action;
77 aDescription.aParameters = std::move(aParameters);
78 aDescription.aParent = "MainWindow";
79 aDescription.aKeyWord = "ScGridWinUIObject";
80
81 UITestLogger::getInstance().logEvent(aDescription);
82}
83
84}
85
86// GlobalName of writer-DocShell from comphelper/classids.hxx
87
88// C U T
89
91{
93
94 ScEditableTester aTester( this );
95 if (!aTester.IsEditable()) // selection editable?
96 {
97 ErrorMessage( aTester.GetMessageId() );
98 return;
99 }
100
101 ScRange aRange; // delete this range
102 if ( GetViewData().GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
103 {
105 ScDocShell* pDocSh = GetViewData().GetDocShell();
107 const bool bRecord(rDoc.IsUndoEnabled()); // Undo/Redo
108
109 ScDocShellModificator aModificator( *pDocSh );
110
111 if ( !rMark.IsMarked() && !rMark.IsMultiMarked() ) // mark the range if not marked yet
112 {
114 InitOwnBlockMode( aRange );
115 rMark.SetMarkArea( aRange );
117 }
118
119 CopyToClip( nullptr, true, false, true/*bIncludeObjects*/ ); // copy to clipboard
120
121 ScAddress aOldEnd( aRange.aEnd ); // combined cells in this range?
122 rDoc.ExtendMerge( aRange, true );
123
124 ScDocumentUniquePtr pUndoDoc;
125 if ( bRecord )
126 {
127 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
128 pUndoDoc->InitUndoSelected( rDoc, rMark );
129 // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
130 ScRange aCopyRange = aRange;
131 aCopyRange.aStart.SetTab(0);
132 aCopyRange.aEnd.SetTab(rDoc.GetTableCount()-1);
134 rDoc.BeginDrawUndo();
135 }
136
137 sal_uInt16 nExtFlags = 0;
138 pDocSh->UpdatePaintExt( nExtFlags, aRange );
139
140 rMark.MarkToMulti();
142 rDoc.DeleteObjectsInSelection( rMark );
143 rMark.MarkToSimple();
144
145 if ( !AdjustRowHeight( aRange.aStart.Row(), aRange.aEnd.Row(), true ) )
146 pDocSh->PostPaint( aRange, PaintPartFlags::Grid, nExtFlags );
147
148 if ( bRecord ) // Draw-Undo now available
149 pDocSh->GetUndoManager()->AddUndoAction(
150 std::make_unique<ScUndoCut>( pDocSh, aRange, aOldEnd, rMark, std::move(pUndoDoc) ) );
151
152 aModificator.SetDocumentModified();
153 pDocSh->UpdateOle(GetViewData());
154
156
157 OUString aStartAddress = aRange.aStart.GetColRowString();
158 OUString aEndAddress = aRange.aEnd.GetColRowString();
159
160 collectUIInformation({{"RANGE", aStartAddress + ":" + aEndAddress}}, "CUT");
161 }
162 else
163 ErrorMessage( STR_NOMULTISELECT );
164}
165
166// C O P Y
167
168bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, bool bCut, bool bApi, bool bIncludeObjects, bool bStopEdit )
169{
170 ScRange aRange;
171 ScMarkType eMarkType = GetViewData().GetSimpleArea( aRange );
173 bool bDone = false;
174
175 if ( eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED )
176 {
177 ScRangeList aRangeList( aRange );
178 bDone = CopyToClip( pClipDoc, aRangeList, bCut, bApi, bIncludeObjects, bStopEdit );
179 }
180 else if (eMarkType == SC_MARK_MULTI)
181 {
182 ScRangeList aRangeList;
183 rMark.MarkToSimple();
184 rMark.FillRangeListWithMarks(&aRangeList, false);
185 bDone = CopyToClip( pClipDoc, aRangeList, bCut, bApi, bIncludeObjects, bStopEdit );
186 }
187 else
188 {
189 if (!bApi)
190 ErrorMessage(STR_NOMULTISELECT);
191 }
192 if( !bCut ){
193 OUString aStartAddress = aRange.aStart.GetColRowString();
194 OUString aEndAddress = aRange.aEnd.GetColRowString();
195 collectUIInformation({{"RANGE", aStartAddress + ":" + aEndAddress}}, "COPY");
196 }
197 return bDone;
198}
199
200// Copy the content of the Range into clipboard.
201bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, const ScRangeList& rRanges, bool bCut, bool bApi, bool bIncludeObjects, bool bStopEdit )
202{
203 if ( rRanges.empty() )
204 return false;
205 if ( bStopEdit )
207
208 bool bDone;
209 if (rRanges.size() > 1) // isMultiRange
210 bDone = CopyToClipMultiRange(pClipDoc, rRanges, bCut, bApi, bIncludeObjects);
211 else
212 bDone = CopyToClipSingleRange(pClipDoc, rRanges, bCut, bIncludeObjects);
213
214 return bDone;
215}
216
217bool ScViewFunc::CopyToClipSingleRange( ScDocument* pClipDoc, const ScRangeList& rRanges, bool bCut, bool bIncludeObjects )
218{
219 ScRange aRange = rRanges[0];
220 ScClipParam aClipParam( aRange, bCut );
221 aClipParam.maRanges = rRanges;
224
225 if (rDoc.HasSelectedBlockMatrixFragment( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), rMark ) )
226 return false;
227
228 bool bSysClip = false;
229 std::shared_ptr<ScDocument> pSysClipDoc;
230 if ( !pClipDoc ) // no clip doc specified
231 {
232 // Create one (deleted by ScTransferObj).
233 pSysClipDoc = std::make_shared<ScDocument>( SCDOCMODE_CLIP );
234 pClipDoc = pSysClipDoc.get();
235 bSysClip = true; // and copy into system
236 }
237 if ( !bCut )
238 {
239 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
240 if ( pChangeTrack )
241 pChangeTrack->ResetLastCut();
242 }
243
244 if ( bSysClip && bIncludeObjects )
245 {
246 bool bAnyOle = rDoc.HasOLEObjectsInArea( aRange );
247 // Update ScGlobal::xDrawClipDocShellRef.
249 }
250
251 // is this necessary?, will setting the doc id upset the
252 // following paste operation with range? would be nicer to just set this always
253 // and lose the 'if' above
254 aClipParam.setSourceDocID( rDoc.GetDocumentID() );
255
256 if (SfxObjectShell* pObjectShell = rDoc.GetDocumentShell())
257 {
258 // Copy document properties from pObjectShell to pClipDoc (to its clip options, as it has no object shell).
259 uno::Reference<util::XCloneable> xCloneable(pObjectShell->getDocProperties(), uno::UNO_QUERY_THROW);
260 std::unique_ptr<ScClipOptions> pOptions(new ScClipOptions);
261 pOptions->m_xDocumentProperties.set(xCloneable->createClone(), uno::UNO_QUERY);
262 pClipDoc->SetClipOptions(std::move(pOptions));
263 }
264
265 rDoc.CopyToClip( aClipParam, pClipDoc, &rMark, false, bIncludeObjects );
266 if (ScDrawLayer* pDrawLayer = pClipDoc->GetDrawLayer())
267 {
268 ScClipParam& rClipDocClipParam = pClipDoc->GetClipParam();
269 ScRangeListVector& rRangesVector = rClipDocClipParam.maProtectedChartRangesVector;
270 SCTAB nTabCount = pClipDoc->GetTableCount();
271 for ( SCTAB nTab = 0; nTab < nTabCount; ++nTab )
272 {
273 SdrPage* pPage = pDrawLayer->GetPage( static_cast< sal_uInt16 >( nTab ) );
274 if ( pPage )
275 {
276 ScChartHelper::FillProtectedChartRangesVector( rRangesVector, rDoc, pPage );
277 }
278 }
279 }
280
281 if ( bSysClip )
282 {
285 }
286 pClipDoc->ExtendMerge( aRange, true );
287
288 if ( bSysClip )
289 {
290 ScDocShell* pDocSh = GetViewData().GetDocShell();
292 pDocSh->FillTransferableObjectDescriptor( aObjDesc );
293 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
294 // maSize is set in ScTransferObj ctor
295
296 rtl::Reference<ScTransferObj> pTransferObj(new ScTransferObj( pSysClipDoc, std::move(aObjDesc) ));
298 {
300 pTransferObj->SetDrawPersist( aPersistRef );// keep persist for ole objects alive
301 }
302 pTransferObj->CopyToClipboard( GetActiveWin() );
303 }
304
305 return true;
306}
307
308bool ScViewFunc::CopyToClipMultiRange( const ScDocument* pInputClipDoc, const ScRangeList& rRanges, bool bCut, bool bApi, bool bIncludeObjects )
309{
310 if (bCut)
311 {
312 // We don't support cutting of multi-selections.
313 if (!bApi)
314 ErrorMessage(STR_NOMULTISELECT);
315 return false;
316 }
317 if (pInputClipDoc)
318 {
319 // TODO: What's this for?
320 if (!bApi)
321 ErrorMessage(STR_NOMULTISELECT);
322 return false;
323 }
324
325 ScClipParam aClipParam( rRanges[0], bCut );
326 aClipParam.maRanges = rRanges;
329 bool bDone = false;
330 bool bSuccess = false;
331 aClipParam.mbCutMode = false;
332
333 do
334 {
336
337 // Check for geometrical feasibility of the ranges.
338 bool bValidRanges = true;
339 ScRange const * p = &aClipParam.maRanges.front();
340 SCCOL nPrevColDelta = 0;
341 SCROW nPrevRowDelta = 0;
342 SCCOL nPrevCol = p->aStart.Col();
343 SCROW nPrevRow = p->aStart.Row();
344 SCCOL nPrevColSize = p->aEnd.Col() - p->aStart.Col() + 1;
345 SCROW nPrevRowSize = p->aEnd.Row() - p->aStart.Row() + 1;
346 for ( size_t i = 1; i < aClipParam.maRanges.size(); ++i )
347 {
348 p = &aClipParam.maRanges[i];
350 p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), rMark) )
351 {
352 if (!bApi)
353 ErrorMessage(STR_MATRIXFRAGMENTERR);
354 return false;
355 }
356
357 SCCOL nColDelta = p->aStart.Col() - nPrevCol;
358 SCROW nRowDelta = p->aStart.Row() - nPrevRow;
359
360 if ((nColDelta && nRowDelta) || (nPrevColDelta && nRowDelta) || (nPrevRowDelta && nColDelta))
361 {
362 bValidRanges = false;
363 break;
364 }
365
366 if (aClipParam.meDirection == ScClipParam::Unspecified)
367 {
368 if (nColDelta)
369 aClipParam.meDirection = ScClipParam::Column;
370 if (nRowDelta)
371 aClipParam.meDirection = ScClipParam::Row;
372 }
373
374 SCCOL nColSize = p->aEnd.Col() - p->aStart.Col() + 1;
375 SCROW nRowSize = p->aEnd.Row() - p->aStart.Row() + 1;
376
377 if (aClipParam.meDirection == ScClipParam::Column && nRowSize != nPrevRowSize)
378 {
379 // column-oriented ranges must have identical row size.
380 bValidRanges = false;
381 break;
382 }
383 if (aClipParam.meDirection == ScClipParam::Row && nColSize != nPrevColSize)
384 {
385 // likewise, row-oriented ranges must have identical
386 // column size.
387 bValidRanges = false;
388 break;
389 }
390
391 nPrevCol = p->aStart.Col();
392 nPrevRow = p->aStart.Row();
393 nPrevColDelta = nColDelta;
394 nPrevRowDelta = nRowDelta;
395 nPrevColSize = nColSize;
396 nPrevRowSize = nRowSize;
397 }
398 if (!bValidRanges)
399 break;
400 rDoc.CopyToClip(aClipParam, pDocClip.get(), &rMark, false, bIncludeObjects );
401
402 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
403 if ( pChangeTrack )
404 pChangeTrack->ResetLastCut(); // no more cut-mode
405
406 ScDocShell* pDocSh = GetViewData().GetDocShell();
408 pDocSh->FillTransferableObjectDescriptor( aObjDesc );
409 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
410 // maSize is set in ScTransferObj ctor
411
412 rtl::Reference<ScTransferObj> pTransferObj(new ScTransferObj( std::move(pDocClip), std::move(aObjDesc) ));
414 {
416 pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive
417 }
418 pTransferObj->CopyToClipboard( GetActiveWin() ); // system clipboard
419
420 bSuccess = true;
421 }
422 while (false);
423
424 if (!bSuccess && !bApi)
425 ErrorMessage(STR_NOMULTISELECT);
426
427 bDone = bSuccess;
428
429 return bDone;
430}
431
433{
434 ScRange aRange;
435 if ( GetViewData().GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
436 {
440 aRange.aStart.Col(), aRange.aStart.Row(),
441 aRange.aEnd.Col(), aRange.aEnd.Row(),
442 rMark ) )
443 {
444 ScDocumentUniquePtr pClipDoc(new ScDocument( SCDOCMODE_CLIP )); // create one (deleted by ScTransferObj)
445
446 bool bAnyOle = rDoc.HasOLEObjectsInArea( aRange, &rMark );
448
449 ScClipParam aClipParam(aRange, false);
450 rDoc.CopyToClip(aClipParam, pClipDoc.get(), &rMark, false, true);
451
453 pClipDoc->ExtendMerge( aRange, true );
454
455 ScDocShell* pDocSh = GetViewData().GetDocShell();
457 pDocSh->FillTransferableObjectDescriptor( aObjDesc );
458 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
459 return new ScTransferObj( std::move(pClipDoc), std::move(aObjDesc) );
460 }
461 }
462
463 return nullptr;
464}
465
466// P A S T E
467
469{
470 ScViewData& rViewData = GetViewData();
471 SCCOL nPosX = rViewData.GetCurX();
472 SCROW nPosY = rViewData.GetCurY();
473 vcl::Window* pWin = GetActiveWin();
474 Point aPos = pWin->PixelToLogic( rViewData.GetScrPos( nPosX, nPosY,
475 rViewData.GetActivePart() ) );
477 if (pDrawClip)
478 {
479 const OUString& aSrcShellID = pDrawClip->GetShellID();
480 OUString aDestShellID = SfxObjectShell::CreateShellID(rViewData.GetDocShell());
481 PasteDraw(aPos, pDrawClip->GetModel(), false, aSrcShellID, aDestShellID);
482 }
483}
484
486{
488
489 vcl::Window* pWin = GetActiveWin();
490 css::uno::Reference<css::datatransfer::XTransferable2> xTransferable2(ScTabViewShell::GetClipData(pWin));
491 const ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(xTransferable2);
492 // keep a reference in case the clipboard is changed during PasteFromClip
493 const ScDrawTransferObj* pDrawClip = ScDrawTransferObj::GetOwnClipboard(xTransferable2);
494 if (pOwnClip)
495 {
498 true ); // allow warning dialog
499 }
500 else if (pDrawClip)
501 PasteDraw();
502 else
503 {
505
506 {
509
510 SotClipboardFormatId nFormat; // output param for GetExchangeAction
511 sal_uInt8 nEventAction; // output param for GetExchangeAction
512
513 uno::Reference<css::datatransfer::XTransferable> xTransferable( aDataHelper.GetXTransferable() );
515 aDataHelper.GetDataFlavorExVector(),
516 SotExchangeDest::SCDOC_FREE_AREA,
519 nFormat, nEventAction, SotClipboardFormatId::NONE,
520 &xTransferable );
521
522 if ( nAction != EXCHG_INOUT_ACTION_NONE )
523 {
524 switch( nAction )
525 {
530 // SotClipboardFormatId::BITMAP
531 // SotClipboardFormatId::PNG
532 // SotClipboardFormatId::GDIMETAFILE
533 // SotClipboardFormatId::SVXB
534 PasteFromSystem(nFormat);
535 break;
536 default:
537 nAction = EXCHG_INOUT_ACTION_NONE;
538 }
539 }
540
541 if ( nAction == EXCHG_INOUT_ACTION_NONE )
542 {
543 // first SvDraw-model, then drawing
544 // (only one drawing is allowed)
545
546 if (aDataHelper.HasFormat( SotClipboardFormatId::DRAWING ))
547 {
548 // special case for tables from drawing
549 if( aDataHelper.HasFormat( SotClipboardFormatId::RTF ) )
550 {
551 PasteFromSystem( SotClipboardFormatId::RTF );
552 }
553 else if( aDataHelper.HasFormat( SotClipboardFormatId::RICHTEXT ) )
554 {
555 PasteFromSystem( SotClipboardFormatId::RICHTEXT );
556 }
557 else
558 {
559 PasteFromSystem( SotClipboardFormatId::DRAWING );
560 }
561 }
562 else if (aDataHelper.HasFormat( SotClipboardFormatId::EMBED_SOURCE ))
563 {
564 // If it's a Writer object, insert RTF instead of OLE
565
566 // Else, if the class id is all-zero, and SYLK is available,
567 // it probably is spreadsheet cells that have been put
568 // on the clipboard by OOo, so use the SYLK. (fdo#31077)
569
570 bool bDoRtf = false;
572 if( aDataHelper.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR, aObjDesc ) )
573 {
574 bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) ||
576 && ( aDataHelper.HasFormat( SotClipboardFormatId::RTF ) || aDataHelper.HasFormat( SotClipboardFormatId::RICHTEXT ) ) );
577 }
578 if ( bDoRtf )
579 PasteFromSystem( aDataHelper.HasFormat( SotClipboardFormatId::RTF ) ? SotClipboardFormatId::RTF : SotClipboardFormatId::RICHTEXT );
580 else if ( aObjDesc.maClassName == SvGlobalName( 0,0,0,0,0,0,0,0,0,0,0 )
581 && aDataHelper.HasFormat( SotClipboardFormatId::SYLK ))
582 PasteFromSystem( SotClipboardFormatId::SYLK );
583 else
584 PasteFromSystem( SotClipboardFormatId::EMBED_SOURCE );
585 }
586 else if (aDataHelper.HasFormat( SotClipboardFormatId::LINK_SOURCE ))
587 PasteFromSystem( SotClipboardFormatId::LINK_SOURCE );
588 // the following format can not affect scenario from #89579#
589 else if (aDataHelper.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ_OLE ))
590 PasteFromSystem( SotClipboardFormatId::EMBEDDED_OBJ_OLE );
591 // SotClipboardFormatId::PRIVATE no longer here (can't work if pOwnClip is NULL)
592 else if (aDataHelper.HasFormat(nBiff8)) // before xxx_OLE formats
593 PasteFromSystem(nBiff8);
594 else if (aDataHelper.HasFormat(nBiff5))
595 PasteFromSystem(nBiff5);
596 else if (aDataHelper.HasFormat(SotClipboardFormatId::RTF))
597 PasteFromSystem(SotClipboardFormatId::RTF);
598 else if (aDataHelper.HasFormat(SotClipboardFormatId::RICHTEXT))
599 PasteFromSystem(SotClipboardFormatId::RICHTEXT);
600 else if (aDataHelper.HasFormat(SotClipboardFormatId::HTML))
601 PasteFromSystem(SotClipboardFormatId::HTML);
602 else if (aDataHelper.HasFormat(SotClipboardFormatId::HTML_SIMPLE))
603 PasteFromSystem(SotClipboardFormatId::HTML_SIMPLE);
604 else if (aDataHelper.HasFormat(SotClipboardFormatId::SYLK))
605 PasteFromSystem(SotClipboardFormatId::SYLK);
606 else if (aDataHelper.HasFormat(SotClipboardFormatId::STRING_TSVC))
607 PasteFromSystem(SotClipboardFormatId::STRING_TSVC);
608 else if (aDataHelper.HasFormat(SotClipboardFormatId::STRING))
609 PasteFromSystem(SotClipboardFormatId::STRING);
610 // xxx_OLE formats come last, like in SotExchange tables
611 else if (aDataHelper.HasFormat( SotClipboardFormatId::EMBED_SOURCE_OLE ))
612 PasteFromSystem( SotClipboardFormatId::EMBED_SOURCE_OLE );
613 else if (aDataHelper.HasFormat( SotClipboardFormatId::LINK_SOURCE_OLE ))
614 PasteFromSystem( SotClipboardFormatId::LINK_SOURCE_OLE );
615 }
616 }
617 }
618 // no exception-> SID_PASTE has FastCall-flag from idl
619 // will be called in case of empty clipboard (#42531#)
620}
621
622void ScViewFunc::PasteFromTransferable( const uno::Reference<datatransfer::XTransferable>& rxTransferable )
623{
624 uno::Reference<lang::XUnoTunnel> xTunnel( rxTransferable, uno::UNO_QUERY );
625
626 if (auto pOwnClip = comphelper::getFromUnoTunnel<ScTransferObj>(xTunnel))
627 {
628 PasteFromClip( InsertDeleteFlags::ALL, pOwnClip->GetDocument(),
630 true ); // allow warning dialog
631 }
632 else if (auto pDrawClip = comphelper::getFromUnoTunnel<ScDrawTransferObj>(xTunnel))
633 {
634 ScViewData& rViewData = GetViewData();
635 SCCOL nPosX = rViewData.GetCurX();
636 SCROW nPosY = rViewData.GetCurY();
637 vcl::Window* pWin = GetActiveWin();
638 Point aPos = pWin->PixelToLogic( rViewData.GetScrPos( nPosX, nPosY, rViewData.GetActivePart() ) );
639 PasteDraw(
640 aPos, pDrawClip->GetModel(), false,
641 pDrawClip->GetShellID(), SfxObjectShell::CreateShellID(rViewData.GetDocShell()));
642 }
643 else
644 {
645 TransferableDataHelper aDataHelper( rxTransferable );
648 SotClipboardFormatId nFormatId = SotClipboardFormatId::NONE;
649 // first SvDraw-model, then drawing
650 // (only one drawing is allowed)
651
652 if (aDataHelper.HasFormat( SotClipboardFormatId::DRAWING ))
653 nFormatId = SotClipboardFormatId::DRAWING;
654 else if (aDataHelper.HasFormat( SotClipboardFormatId::SVXB ))
655 nFormatId = SotClipboardFormatId::SVXB;
656 else if (aDataHelper.HasFormat( SotClipboardFormatId::EMBED_SOURCE ))
657 {
658 // If it's a Writer object, insert RTF instead of OLE
659 bool bDoRtf = false;
661 if( aDataHelper.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR, aObjDesc ) )
662 {
663 bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) ||
665 && ( aDataHelper.HasFormat( SotClipboardFormatId::RTF ) || aDataHelper.HasFormat( SotClipboardFormatId::RICHTEXT ) ));
666 }
667 if ( bDoRtf )
668 nFormatId = aDataHelper.HasFormat( SotClipboardFormatId::RTF ) ? SotClipboardFormatId::RTF : SotClipboardFormatId::RICHTEXT;
669 else
670 nFormatId = SotClipboardFormatId::EMBED_SOURCE;
671 }
672 else if (aDataHelper.HasFormat( SotClipboardFormatId::LINK_SOURCE ))
673 nFormatId = SotClipboardFormatId::LINK_SOURCE;
674 // the following format can not affect scenario from #89579#
675 else if (aDataHelper.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ_OLE ))
676 nFormatId = SotClipboardFormatId::EMBEDDED_OBJ_OLE;
677 // SotClipboardFormatId::PRIVATE no longer here (can't work if pOwnClip is NULL)
678 else if (aDataHelper.HasFormat(nBiff8)) // before xxx_OLE formats
679 nFormatId = nBiff8;
680 else if (aDataHelper.HasFormat(nBiff5))
681 nFormatId = nBiff5;
682 else if (aDataHelper.HasFormat(SotClipboardFormatId::RTF))
683 nFormatId = SotClipboardFormatId::RTF;
684 else if (aDataHelper.HasFormat(SotClipboardFormatId::RICHTEXT))
685 nFormatId = SotClipboardFormatId::RICHTEXT;
686 else if (aDataHelper.HasFormat(SotClipboardFormatId::HTML))
687 nFormatId = SotClipboardFormatId::HTML;
688 else if (aDataHelper.HasFormat(SotClipboardFormatId::HTML_SIMPLE))
689 nFormatId = SotClipboardFormatId::HTML_SIMPLE;
690 else if (aDataHelper.HasFormat(SotClipboardFormatId::SYLK))
691 nFormatId = SotClipboardFormatId::SYLK;
692 else if (aDataHelper.HasFormat(SotClipboardFormatId::STRING_TSVC))
693 nFormatId = SotClipboardFormatId::STRING_TSVC;
694 else if (aDataHelper.HasFormat(SotClipboardFormatId::STRING))
695 nFormatId = SotClipboardFormatId::STRING;
696 else if (aDataHelper.HasFormat(SotClipboardFormatId::GDIMETAFILE))
697 nFormatId = SotClipboardFormatId::GDIMETAFILE;
698 else if (aDataHelper.HasFormat(SotClipboardFormatId::BITMAP))
699 nFormatId = SotClipboardFormatId::BITMAP;
700 // xxx_OLE formats come last, like in SotExchange tables
701 else if (aDataHelper.HasFormat( SotClipboardFormatId::EMBED_SOURCE_OLE ))
702 nFormatId = SotClipboardFormatId::EMBED_SOURCE_OLE;
703 else if (aDataHelper.HasFormat( SotClipboardFormatId::LINK_SOURCE_OLE ))
704 nFormatId = SotClipboardFormatId::LINK_SOURCE_OLE;
705 else
706 return;
707
708 PasteDataFormat( nFormatId, aDataHelper.GetTransferable(),
709 GetViewData().GetCurX(), GetViewData().GetCurY(), nullptr );
710 }
711}
712
714{
716
717 bool bRet = true;
718 vcl::Window* pWin = GetActiveWin();
719 // keep a reference in case the clipboard is changed during PasteFromClip
721 if ( nFormatId == SotClipboardFormatId::NONE && pOwnClip )
722 {
725 !bApi ); // allow warning dialog
726 }
727 else
728 {
730 if ( !aDataHelper.GetTransferable().is() )
731 return false;
732
733 SCCOL nPosX = 0;
734 SCROW nPosY = 0;
735
736 ScViewData& rViewData = GetViewData();
737 ScRange aRange;
738 if ( rViewData.GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
739 {
740 nPosX = aRange.aStart.Col();
741 nPosY = aRange.aStart.Row();
742 }
743 else
744 {
745 nPosX = rViewData.GetCurX();
746 nPosY = rViewData.GetCurY();
747 }
748
749 bRet = PasteDataFormat( nFormatId, aDataHelper.GetTransferable(),
750 nPosX, nPosY,
751 nullptr, false, !bApi ); // allow warning dialog
752
753 if ( !bRet && !bApi )
754 {
755 ErrorMessage(STR_PASTE_ERROR);
756 }
758 {
759 SfxViewShell* pViewShell = rViewData.GetViewShell();
760 ScTabViewShell::notifyAllViewsSheetGeomInvalidation(pViewShell, true /* bColumns */, true /* bRows */,
761 true /* bSizes */, false /* bHidden */, false /* bFiltered */, false /* bGroups */, rViewData.GetTabNo());
762 }
763 }
764 return bRet;
765}
766
767// P A S T E
768
770 const uno::Reference<datatransfer::XTransferable>& rxTransferable,
771 SdrObject& rHitObj)
772{
773 TransferableDataHelper aDataHelper( rxTransferable );
774
775 if ( aDataHelper.HasFormat( SotClipboardFormatId::SVXB ) )
776 {
778 ScDrawView* pScDrawView = GetScDrawView();
779
780 if( pScDrawView && aDataHelper.GetSotStorageStream( SotClipboardFormatId::SVXB, xStm ) )
781 {
782 Graphic aGraphic;
783 TypeSerializer aSerializer(*xStm);
784 aSerializer.readGraphic(aGraphic);
785
786 const OUString aBeginUndo(ScResId(STR_UNDO_DRAGDROP));
787
788 if(pScDrawView->ApplyGraphicToObject( rHitObj, aGraphic, aBeginUndo, "" ))
789 {
790 return true;
791 }
792 }
793 }
794 else if ( aDataHelper.HasFormat( SotClipboardFormatId::GDIMETAFILE ) )
795 {
796 GDIMetaFile aMtf;
797 ScDrawView* pScDrawView = GetScDrawView();
798
799 if( pScDrawView && aDataHelper.GetGDIMetaFile( SotClipboardFormatId::GDIMETAFILE, aMtf ) )
800 {
801 const OUString aBeginUndo(ScResId(STR_UNDO_DRAGDROP));
802
803 if(pScDrawView->ApplyGraphicToObject( rHitObj, Graphic(aMtf), aBeginUndo, "" ))
804 {
805 return true;
806 }
807 }
808 }
809 else if ( aDataHelper.HasFormat( SotClipboardFormatId::BITMAP ) || aDataHelper.HasFormat( SotClipboardFormatId::PNG ) )
810 {
811 BitmapEx aBmpEx;
812 ScDrawView* pScDrawView = GetScDrawView();
813
814 if( pScDrawView && aDataHelper.GetBitmapEx( SotClipboardFormatId::BITMAP, aBmpEx ) )
815 {
816 const OUString aBeginUndo(ScResId(STR_UNDO_DRAGDROP));
817
818 if(pScDrawView->ApplyGraphicToObject( rHitObj, Graphic(aBmpEx), aBeginUndo, "" ))
819 {
820 return true;
821 }
822 }
823 }
824
825 return false;
826}
827
828static bool lcl_SelHasAttrib( const ScDocument& rDoc, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
829 const ScMarkData& rTabSelection, HasAttrFlags nMask )
830{
831 return std::any_of(rTabSelection.begin(), rTabSelection.end(),
832 [&](const SCTAB& rTab) { return rDoc.HasAttrib( nCol1, nRow1, rTab, nCol2, nRow2, rTab, nMask ); });
833}
834
835// paste into sheet:
836
837// internal paste
838
839namespace {
840
841bool checkDestRangeForOverwrite(const ScRangeList& rDestRanges, const ScDocument& rDoc, const ScMarkData& rMark, weld::Window* pParentWnd)
842{
843 bool bIsEmpty = true;
844 size_t nRangeSize = rDestRanges.size();
845 for (const auto& rTab : rMark)
846 {
847 for (size_t i = 0; i < nRangeSize && bIsEmpty; ++i)
848 {
849 const ScRange& rRange = rDestRanges[i];
850 bIsEmpty = rDoc.IsBlockEmpty(
851 rRange.aStart.Col(), rRange.aStart.Row(),
852 rRange.aEnd.Col(), rRange.aEnd.Row(), rTab );
853 }
854 if (!bIsEmpty)
855 break;
856 }
857
858 if (!bIsEmpty)
859 {
860 ScReplaceWarnBox aBox(pParentWnd);
861 if (aBox.run() != RET_YES)
862 {
863 // changing the configuration is within the ScReplaceWarnBox
864 return false;
865 }
866 }
867 return true;
868}
869
870}
871
873 ScPasteFunc nFunction, bool bSkipEmptyCells,
874 bool bTranspose, bool bAsLink,
875 InsCellCmd eMoveMode, InsertDeleteFlags nUndoExtraFlags,
876 bool bAllowDialogs )
877{
878 if (!pClipDoc)
879 {
880 OSL_FAIL("PasteFromClip: pClipDoc=0 not allowed");
881 return false;
882 }
883
884 if (GetViewData().SelectionForbidsPaste(pClipDoc))
885 return false;
886
887 // undo: save all or no content
889 if (nFlags & InsertDeleteFlags::CONTENTS)
890 nContFlags |= InsertDeleteFlags::CONTENTS;
891 if (nFlags & InsertDeleteFlags::ATTRIB)
892 nContFlags |= InsertDeleteFlags::ATTRIB;
893 // move attributes to undo without copying them from clip to doc
894 InsertDeleteFlags nUndoFlags = nContFlags;
895 if (nUndoExtraFlags & InsertDeleteFlags::ATTRIB)
896 nUndoFlags |= InsertDeleteFlags::ATTRIB;
897 // do not copy note captions into undo document
898 nUndoFlags |= InsertDeleteFlags::NOCAPTIONS;
899
900 ScClipParam& rClipParam = pClipDoc->GetClipParam();
901 if (rClipParam.isMultiRange())
902 {
903 // Source data is multi-range.
904 return PasteMultiRangesFromClip(nFlags, pClipDoc, nFunction, bSkipEmptyCells, bTranspose,
905 bAsLink, bAllowDialogs, eMoveMode, nUndoFlags);
906 }
907
909 if (rMark.IsMultiMarked())
910 {
911 // Source data is single-range but destination is multi-range.
913 nFlags, pClipDoc, nFunction, bSkipEmptyCells, bTranspose, bAsLink, bAllowDialogs,
914 eMoveMode, nUndoFlags);
915 }
916
917 bool bCutMode = pClipDoc->IsCutMode(); // if transposing, take from original clipdoc
918 bool bIncludeFiltered = bCutMode;
919
920 // paste drawing: also if InsertDeleteFlags::NOTE is set (to create drawing layer for note captions)
921 bool bPasteDraw = ( pClipDoc->GetDrawLayer() && ( nFlags & (InsertDeleteFlags::OBJECTS|InsertDeleteFlags::NOTE) ) );
922
923 ScDocShellRef aTransShellRef; // for objects in xTransClip - must remain valid as long as xTransClip
924 ScDocument* pOrigClipDoc = nullptr;
925 ScDocumentUniquePtr xTransClip;
926 if ( bTranspose )
927 {
928 SCCOL nX;
929 SCROW nY;
930 // include filtered rows until TransposeClip can skip them
931 pClipDoc->GetClipArea( nX, nY, true );
932 if ( nY > static_cast<sal_Int32>(pClipDoc->MaxCol()) ) // too many lines for transpose
933 {
934 ErrorMessage(STR_PASTE_FULL);
935 return false;
936 }
937 pOrigClipDoc = pClipDoc; // refs
938
939 if ( bPasteDraw )
940 {
941 aTransShellRef = new ScDocShell; // DocShell needs a Ref immediately
942 aTransShellRef->DoInitNew();
943 }
944 ScDrawLayer::SetGlobalDrawPersist( aTransShellRef.get() );
945
946 xTransClip.reset( new ScDocument( SCDOCMODE_CLIP ));
947 pClipDoc->TransposeClip(xTransClip.get(), nFlags, bAsLink, bIncludeFiltered);
948 pClipDoc = xTransClip.get();
949
951 }
952
953 // TODO: position this call better for performance.
955
956 SCCOL nStartCol;
957 SCROW nStartRow;
958 SCTAB nStartTab;
959 SCCOL nEndCol;
960 SCROW nEndRow;
961 SCTAB nEndTab;
962 SCCOL nClipSizeX;
963 SCROW nClipSizeY;
964 pClipDoc->GetClipArea( nClipSizeX, nClipSizeY, true ); // size in clipboard doc
965
966 // size in target doc: include filtered rows only if CutMode is set
967 SCCOL nDestSizeX;
968 SCROW nDestSizeY;
969 pClipDoc->GetClipArea( nDestSizeX, nDestSizeY, bIncludeFiltered );
970
972 ScDocShell* pDocSh = GetViewData().GetDocShell();
973 SfxUndoManager* pUndoMgr = pDocSh->GetUndoManager();
974 const bool bRecord(rDoc.IsUndoEnabled());
975
976 ScDocShellModificator aModificator( *pDocSh );
977
978 ScRange aMarkRange;
979 ScMarkData aFilteredMark( rMark); // local copy for all modifications
980 ScMarkType eMarkType = GetViewData().GetSimpleArea( aMarkRange, aFilteredMark);
981 bool bMarkIsFiltered = (eMarkType == SC_MARK_SIMPLE_FILTERED);
982 bool bNoPaste = ((eMarkType != SC_MARK_SIMPLE && !bMarkIsFiltered) ||
983 (bMarkIsFiltered && (eMoveMode != INS_NONE || bAsLink)));
984
985 if (!bNoPaste)
986 {
987 if (!rMark.IsMarked())
988 {
989 // Create a selection with clipboard row count and check that for
990 // filtered.
991 nStartCol = GetViewData().GetCurX();
992 nStartRow = GetViewData().GetCurY();
993 nStartTab = GetViewData().GetTabNo();
994 nEndCol = nStartCol + nDestSizeX;
995 nEndRow = nStartRow + nDestSizeY;
996 nEndTab = nStartTab;
997 aMarkRange = ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
998 if (ScViewUtil::HasFiltered(aMarkRange, rDoc))
999 {
1000 bMarkIsFiltered = true;
1001 // Fit to clipboard's row count unfiltered rows. If there is no
1002 // fit assume that pasting is not possible. Note that nDestSizeY is
1003 // size-1 (difference).
1004 if (!ScViewUtil::FitToUnfilteredRows(aMarkRange, rDoc, nDestSizeY+1))
1005 bNoPaste = true;
1006 }
1007 aFilteredMark.SetMarkArea( aMarkRange);
1008 }
1009 else
1010 {
1011 // Expand the marked area when the destination area is larger than the
1012 // current selection, to get the undo do the right thing. (i#106711)
1013 ScRange aRange = aFilteredMark.GetMarkArea();
1014 if( (aRange.aEnd.Col() - aRange.aStart.Col()) < nDestSizeX )
1015 {
1016 aRange.aEnd.SetCol(aRange.aStart.Col() + nDestSizeX);
1017 aFilteredMark.SetMarkArea(aRange);
1018 }
1019 }
1020 }
1021
1022 if (bNoPaste)
1023 {
1024 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
1025 return false;
1026 }
1027
1028 SCROW nUnfilteredRows = aMarkRange.aEnd.Row() - aMarkRange.aStart.Row() + 1;
1029 ScRangeList aRangeList;
1030 if (bMarkIsFiltered)
1031 {
1032 ScViewUtil::UnmarkFiltered(aFilteredMark, rDoc);
1033 aFilteredMark.FillRangeListWithMarks( &aRangeList, false);
1034 nUnfilteredRows = 0;
1035 size_t ListSize = aRangeList.size();
1036 for ( size_t i = 0; i < ListSize; ++i )
1037 {
1038 ScRange & r = aRangeList[i];
1039 nUnfilteredRows += r.aEnd.Row() - r.aStart.Row() + 1;
1040 }
1041#if 0
1042 /* This isn't needed but could be a desired restriction. */
1043 // For filtered, destination rows have to be an exact multiple of
1044 // source rows. Note that nDestSizeY is size-1 (difference), so
1045 // nDestSizeY==0 fits always.
1046 if ((nUnfilteredRows % (nDestSizeY+1)) != 0)
1047 {
1048 /* FIXME: this should be a more descriptive error message then. */
1049 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
1050 return false;
1051 }
1052#endif
1053 }
1054
1055 // Also for a filtered selection the area is used, for undo et al.
1056 if ( aFilteredMark.IsMarked() || bMarkIsFiltered )
1057 {
1058 aMarkRange.GetVars( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
1059 SCCOL nBlockAddX = nEndCol-nStartCol;
1060 SCROW nBlockAddY = nEndRow-nStartRow;
1061
1062 // request, if the selection is greater than one row/column, but smaller
1063 // as the Clipboard (then inserting is done beyond the selection)
1064
1065 // ClipSize is not size, but difference
1066 if ( ( nBlockAddX != 0 && nBlockAddX < nDestSizeX ) ||
1067 ( nBlockAddY != 0 && nBlockAddY < nDestSizeY ) ||
1068 ( bMarkIsFiltered && nUnfilteredRows < nDestSizeY+1 ) )
1069 {
1070 ScWaitCursorOff aWaitOff( GetFrameWin() );
1071 OUString aMessage = ScResId( STR_PASTE_BIGGER );
1072
1073 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetViewData().GetDialogParent(),
1074 VclMessageType::Question, VclButtonsType::YesNo,
1075 aMessage));
1076 xQueryBox->set_default_response(RET_NO);
1077 if (xQueryBox->run() != RET_YES)
1078 {
1079 return false;
1080 }
1081 }
1082
1083 if (nBlockAddX <= nDestSizeX)
1084 nEndCol = nStartCol + nDestSizeX;
1085
1086 if (nBlockAddY <= nDestSizeY)
1087 {
1088 nEndRow = nStartRow + nDestSizeY;
1089 if (bMarkIsFiltered || nEndRow > aMarkRange.aEnd.Row())
1090 {
1091 // Same as above if nothing was marked: re-fit selection to
1092 // unfiltered rows. Extending the selection actually may
1093 // introduce filtered rows where there weren't any before, so
1094 // we also need to test for that.
1095 aMarkRange = ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
1096 if (bMarkIsFiltered || ScViewUtil::HasFiltered(aMarkRange, rDoc))
1097 {
1098 bMarkIsFiltered = true;
1099 // Worst case: all rows up to the end of the sheet are filtered.
1100 if (!ScViewUtil::FitToUnfilteredRows(aMarkRange, rDoc, nDestSizeY+1))
1101 {
1102 ErrorMessage(STR_PASTE_FULL);
1103 return false;
1104 }
1105 }
1106 aMarkRange.GetVars( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
1107 aFilteredMark.SetMarkArea( aMarkRange);
1108 if (bMarkIsFiltered)
1109 {
1110 ScViewUtil::UnmarkFiltered(aFilteredMark, rDoc);
1111 aFilteredMark.FillRangeListWithMarks( &aRangeList, true);
1112 }
1113 }
1114 }
1115 }
1116 else
1117 {
1118 nStartCol = GetViewData().GetCurX();
1119 nStartRow = GetViewData().GetCurY();
1120 nStartTab = GetViewData().GetTabNo();
1121 nEndCol = nStartCol + nDestSizeX;
1122 nEndRow = nStartRow + nDestSizeY;
1123 nEndTab = nStartTab;
1124 }
1125
1126 bool bOffLimits = !rDoc.ValidCol(nEndCol) || !rDoc.ValidRow(nEndRow);
1127
1128 // target-range, as displayed:
1129 ScRange aUserRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab );
1130
1131 // should lines be inserted?
1132 // ( too large nEndCol/nEndRow are detected below)
1133 bool bInsertCells = ( eMoveMode != INS_NONE && !bOffLimits );
1134 if ( bInsertCells )
1135 {
1136 // Instead of EnterListAction, the paste undo action is merged into the
1137 // insert action, so Repeat can insert the right cells
1138
1139 MarkRange( aUserRange ); // set through CopyFromClip
1140
1141 // CutMode is reset on insertion of cols/rows but needed again on cell move
1142 bool bCut = pClipDoc->IsCutMode();
1143 if (!InsertCells( eMoveMode, bRecord, true )) // is inserting possible?
1144 {
1145 return false;
1146 // #i21036# EnterListAction isn't used, and InsertCells doesn't insert
1147 // its undo action on failure, so no undo handling is needed here
1148 }
1149 if ( bCut )
1150 pClipDoc->SetCutMode( bCut );
1151 }
1152 else if (!bOffLimits)
1153 {
1154 bool bAskIfNotEmpty = bAllowDialogs &&
1155 ( nFlags & InsertDeleteFlags::CONTENTS ) &&
1156 nFunction == ScPasteFunc::NONE &&
1157 SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1158 if ( bAskIfNotEmpty )
1159 {
1160 ScRangeList aTestRanges(aUserRange);
1161 if (!checkDestRangeForOverwrite(aTestRanges, rDoc, aFilteredMark, GetViewData().GetDialogParent()))
1162 return false;
1163 }
1164 }
1165
1166 SCCOL nClipStartX; // enlarge clipboard-range
1167 SCROW nClipStartY;
1168 pClipDoc->GetClipStart( nClipStartX, nClipStartY );
1169 SCCOL nUndoEndCol = nClipStartX + nClipSizeX;
1170 SCROW nUndoEndRow = nClipStartY + nClipSizeY; // end of source area in clipboard document
1171 bool bClipOver = false;
1172 // #i68690# ExtendMerge for the clip doc must be called with the clipboard's sheet numbers.
1173 // The same end column/row can be used for all calls because the clip doc doesn't contain
1174 // content outside the clip area.
1175 for (SCTAB nClipTab=0; nClipTab < pClipDoc->GetTableCount(); nClipTab++)
1176 if ( pClipDoc->HasTable(nClipTab) )
1177 if ( pClipDoc->ExtendMerge( nClipStartX,nClipStartY, nUndoEndCol,nUndoEndRow, nClipTab ) )
1178 bClipOver = true;
1179 nUndoEndCol -= nClipStartX + nClipSizeX;
1180 nUndoEndRow -= nClipStartY + nClipSizeY; // now contains only the difference added by ExtendMerge
1181 nUndoEndCol = sal::static_int_cast<SCCOL>( nUndoEndCol + nEndCol );
1182 nUndoEndRow = sal::static_int_cast<SCROW>( nUndoEndRow + nEndRow ); // destination area, expanded for merged cells
1183
1184 if (nUndoEndCol>pClipDoc->MaxCol() || nUndoEndRow>pClipDoc->MaxRow())
1185 {
1186 ErrorMessage(STR_PASTE_FULL);
1187 return false;
1188 }
1189
1190 rDoc.ExtendMergeSel( nStartCol,nStartRow, nUndoEndCol,nUndoEndRow, aFilteredMark );
1191
1192 // check cell-protection
1193
1194 ScEditableTester aTester( rDoc, nStartTab, nStartCol,nStartRow, nUndoEndCol,nUndoEndRow );
1195 if (!aTester.IsEditable())
1196 {
1197 ErrorMessage(aTester.GetMessageId());
1198 return false;
1199 }
1200
1203
1204 ScDocFunc& rDocFunc = pDocSh->GetDocFunc();
1205 if ( bRecord )
1206 {
1207 OUString aUndo = ScResId( pClipDoc->IsCutMode() ? STR_UNDO_MOVE : STR_UNDO_COPY );
1208 pUndoMgr->EnterListAction( aUndo, aUndo, 0, GetViewData().GetViewShell()->GetViewShellId() );
1209 }
1210
1211 if (bClipOver)
1212 if (lcl_SelHasAttrib( rDoc, nStartCol,nStartRow, nUndoEndCol,nUndoEndRow, aFilteredMark, HasAttrFlags::Overlapped ))
1213 { // "Cell merge not possible if cells already merged"
1214 ScDocAttrIterator aIter( rDoc, nStartTab, nStartCol, nStartRow, nUndoEndCol, nUndoEndRow );
1215 const ScPatternAttr* pPattern = nullptr;
1216 SCCOL nCol = -1;
1217 SCROW nRow1 = -1;
1218 SCROW nRow2 = -1;
1219 while ( ( pPattern = aIter.GetNext( nCol, nRow1, nRow2 ) ) != nullptr )
1220 {
1221 const ScMergeAttr& rMergeFlag = pPattern->GetItem(ATTR_MERGE);
1222 const ScMergeFlagAttr& rMergeFlagAttr = pPattern->GetItem(ATTR_MERGE_FLAG);
1223 if (rMergeFlag.IsMerged() || rMergeFlagAttr.IsOverlapped())
1224 {
1225 ScRange aRange(nCol, nRow1, nStartTab);
1226 rDoc.ExtendOverlapped(aRange);
1227 rDoc.ExtendMerge(aRange, true);
1228 rDocFunc.UnmergeCells(aRange, bRecord, nullptr /*TODO: should pass combined UndoDoc if bRecord*/);
1229 }
1230 }
1231 }
1232
1233 if ( !bCutMode )
1234 {
1235 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
1236 if ( pChangeTrack )
1237 pChangeTrack->ResetLastCut(); // no more cut-mode
1238 }
1239
1240 bool bColInfo = ( nStartRow==0 && nEndRow==rDoc.MaxRow() );
1241 bool bRowInfo = ( nStartCol==0 && nEndCol==rDoc.MaxCol() );
1242
1243 ScDocumentUniquePtr pUndoDoc;
1244 std::unique_ptr<ScDocument> pRefUndoDoc;
1245 std::unique_ptr<ScRefUndoData> pUndoData;
1246
1247 if ( bRecord )
1248 {
1249 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1250 pUndoDoc->InitUndoSelected( rDoc, aFilteredMark, bColInfo, bRowInfo );
1251
1252 // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
1253 SCTAB nTabCount = rDoc.GetTableCount();
1254 rDoc.CopyToDocument( nStartCol, nStartRow, 0, nUndoEndCol, nUndoEndRow, nTabCount-1,
1255 nUndoFlags, false, *pUndoDoc );
1256
1257 if ( bCutMode )
1258 {
1259 pRefUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1260 pRefUndoDoc->InitUndo( rDoc, 0, nTabCount-1 );
1261
1262 pUndoData.reset(new ScRefUndoData( &rDoc ));
1263 }
1264 }
1265
1266 sal_uInt16 nExtFlags = 0;
1267 pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab,
1268 nEndCol, nEndRow, nEndTab ); // content before the change
1269
1270 if (GetViewData().IsActive())
1271 {
1272 DoneBlockMode();
1273 InitOwnBlockMode( aUserRange );
1274 }
1275 rMark.SetMarkArea( aUserRange );
1277
1278 // copy from clipboard
1279 // save original data in case of calculation
1280
1281 ScDocumentUniquePtr pMixDoc;
1282 if (nFunction != ScPasteFunc::NONE)
1283 {
1284 bSkipEmptyCells = false;
1285 if ( nFlags & InsertDeleteFlags::CONTENTS )
1286 {
1287 pMixDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1288 pMixDoc->InitUndo( rDoc, nStartTab, nEndTab );
1289 rDoc.CopyToDocument(nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
1290 InsertDeleteFlags::CONTENTS, false, *pMixDoc);
1291 }
1292 }
1293
1294 /* Make draw layer and start drawing undo.
1295 - Needed before AdjustBlockHeight to track moved drawing objects.
1296 - Needed before rDoc.CopyFromClip to track inserted note caption objects.
1297 */
1298 if ( bPasteDraw )
1299 pDocSh->MakeDrawLayer();
1300 if ( bRecord )
1301 rDoc.BeginDrawUndo();
1302
1303 InsertDeleteFlags nNoObjFlags = nFlags & ~InsertDeleteFlags::OBJECTS;
1304 if (!bAsLink)
1305 {
1306 // copy normally (original range)
1307 rDoc.CopyFromClip( aUserRange, aFilteredMark, nNoObjFlags,
1308 pRefUndoDoc.get(), pClipDoc, true, false, bIncludeFiltered,
1309 bSkipEmptyCells, (bMarkIsFiltered ? &aRangeList : nullptr) );
1310
1311 // adapt refs manually in case of transpose
1312 if ( bTranspose && bCutMode && (nFlags & InsertDeleteFlags::CONTENTS) )
1313 rDoc.UpdateTranspose( aUserRange.aStart, pOrigClipDoc, aFilteredMark, pRefUndoDoc.get() );
1314 }
1315 else if (!bTranspose)
1316 {
1317 // copy with bAsLink=TRUE
1318 rDoc.CopyFromClip( aUserRange, aFilteredMark, nNoObjFlags, pRefUndoDoc.get(), pClipDoc,
1319 true, true, bIncludeFiltered, bSkipEmptyCells );
1320 }
1321 else
1322 {
1323 // copy all content (TransClipDoc contains only formula)
1324 rDoc.CopyFromClip( aUserRange, aFilteredMark, nContFlags, pRefUndoDoc.get(), pClipDoc );
1325 }
1326
1327 // skipped rows and merged cells don't mix
1328 if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
1329 rDocFunc.UnmergeCells( aUserRange, false, nullptr );
1330
1331 rDoc.ExtendMergeSel( nStartCol, nStartRow, nEndCol, nEndRow, aFilteredMark, true ); // refresh
1332 // new range
1333
1334 if ( pMixDoc ) // calculate with original data?
1335 {
1336 rDoc.MixDocument( aUserRange, nFunction, bSkipEmptyCells, *pMixDoc );
1337 }
1338 pMixDoc.reset();
1339
1340 AdjustBlockHeight(); // update row heights before pasting objects
1341
1342 ::std::vector< OUString > aExcludedChartNames;
1343 SdrPage* pPage = nullptr;
1344
1345 if ( nFlags & InsertDeleteFlags::OBJECTS )
1346 {
1347 ScDrawView* pScDrawView = GetScDrawView();
1348 SdrModel* pModel = ( pScDrawView ? pScDrawView->GetModel() : nullptr );
1349 pPage = ( pModel ? pModel->GetPage( static_cast< sal_uInt16 >( nStartTab ) ) : nullptr );
1350 if ( pPage )
1351 {
1352 ScChartHelper::GetChartNames( aExcludedChartNames, pPage );
1353 }
1354
1355 // Paste the drawing objects after the row heights have been updated.
1356
1357 rDoc.CopyFromClip( aUserRange, aFilteredMark, InsertDeleteFlags::OBJECTS, pRefUndoDoc.get(), pClipDoc,
1358 true, false, bIncludeFiltered );
1359 }
1360
1361 pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab,
1362 nEndCol, nEndRow, nEndTab ); // content after the change
1363
1364 // if necessary, delete autofilter-heads
1365 if (bCutMode)
1366 if (rDoc.RefreshAutoFilter( nClipStartX,nClipStartY, nClipStartX+nClipSizeX,
1367 nClipStartY+nClipSizeY, nStartTab ))
1368 {
1369 pDocSh->PostPaint(
1370 ScRange(nClipStartX, nClipStartY, nStartTab, nClipStartX+nClipSizeX, nClipStartY, nStartTab),
1372 }
1373
1375
1376 if ( bRecord )
1377 {
1378 ScDocumentUniquePtr pRedoDoc;
1379 // copy redo data after appearance of the first undo
1380 // don't create Redo-Doc without RefUndoDoc
1381
1382 if (pRefUndoDoc)
1383 {
1384 pRedoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1385 pRedoDoc->InitUndo( rDoc, nStartTab, nEndTab, bColInfo, bRowInfo );
1386
1387 // move adapted refs to Redo-Doc
1388
1389 SCTAB nTabCount = rDoc.GetTableCount();
1390 pRedoDoc->AddUndoTab( 0, nTabCount-1 );
1391 rDoc.CopyUpdated( pRefUndoDoc.get(), pRedoDoc.get() );
1392
1393 // move old refs to Undo-Doc
1394
1395 // not charts?
1396 pUndoDoc->AddUndoTab( 0, nTabCount-1 );
1397 pRefUndoDoc->DeleteArea( nStartCol, nStartRow, nEndCol, nEndRow, aFilteredMark, InsertDeleteFlags::ALL );
1398 pRefUndoDoc->CopyToDocument( 0,0,0, pUndoDoc->MaxCol(), pUndoDoc->MaxRow(), nTabCount-1,
1399 InsertDeleteFlags::FORMULA, false, *pUndoDoc );
1400 pRefUndoDoc.reset();
1401 }
1402
1403 // DeleteUnchanged for pUndoData is in ScUndoPaste ctor,
1404 // UndoData for redo is made during first undo
1405
1406 ScUndoPasteOptions aOptions; // store options for repeat
1407 aOptions.nFunction = nFunction;
1408 aOptions.bSkipEmptyCells = bSkipEmptyCells;
1409 aOptions.bTranspose = bTranspose;
1410 aOptions.bAsLink = bAsLink;
1411 aOptions.eMoveMode = eMoveMode;
1412
1413 std::unique_ptr<SfxUndoAction> pUndo(new ScUndoPaste(
1414 pDocSh, ScRange(nStartCol, nStartRow, nStartTab, nUndoEndCol, nUndoEndRow, nEndTab),
1415 aFilteredMark, std::move(pUndoDoc), std::move(pRedoDoc), nFlags | nUndoFlags, std::move(pUndoData),
1416 false, &aOptions )); // false = Redo data not yet copied
1417
1418 if ( bInsertCells )
1419 {
1420 // Merge the paste undo action into the insert action.
1421 // Use ScUndoWrapper so the ScUndoPaste pointer can be stored in the insert action.
1422
1423 pUndoMgr->AddUndoAction( std::make_unique<ScUndoWrapper>( std::move(pUndo) ), true );
1424 }
1425 else
1426 pUndoMgr->AddUndoAction( std::move(pUndo) );
1427 pUndoMgr->LeaveListAction();
1428 }
1429
1431 if (bColInfo)
1432 {
1433 nPaint |= PaintPartFlags::Top;
1434 nUndoEndCol = rDoc.MaxCol(); // just for drawing !
1435 }
1436 if (bRowInfo)
1437 {
1438 nPaint |= PaintPartFlags::Left;
1439 nUndoEndRow = rDoc.MaxRow(); // just for drawing !
1440 }
1441 pDocSh->PostPaint(
1442 ScRange(nStartCol, nStartRow, nStartTab, nUndoEndCol, nUndoEndRow, nEndTab),
1443 nPaint, nExtFlags);
1444 // AdjustBlockHeight has already been called above
1445
1446 aModificator.SetDocumentModified();
1447 PostPasteFromClip(aUserRange, rMark);
1448
1449 if ( nFlags & InsertDeleteFlags::OBJECTS )
1450 {
1451 ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>( pDocSh->GetModel() );
1452 if ( pPage && pModelObj )
1453 {
1454 bool bSameDoc = ( rClipParam.getSourceDocID() == rDoc.GetDocumentID() );
1455 const ScRangeListVector& rProtectedChartRangesVector( rClipParam.maProtectedChartRangesVector );
1456 ScChartHelper::CreateProtectedChartListenersAndNotify( rDoc, pPage, pModelObj, nStartTab,
1457 rProtectedChartRangesVector, aExcludedChartNames, bSameDoc );
1458 }
1459 }
1460 OUString aStartAddress = aMarkRange.aStart.GetColRowString();
1461 OUString aEndAddress = aMarkRange.aEnd.GetColRowString();
1462 collectUIInformation({{"RANGE", aStartAddress + ":" + aEndAddress}}, "PASTE");
1463 return true;
1464}
1465
1467 ScPasteFunc nFunction, bool bSkipEmptyCells,
1468 bool bTranspose, bool bAsLink,
1469 bool bAllowDialogs, InsCellCmd eMoveMode,
1470 InsertDeleteFlags nUndoFlags)
1471{
1472 ScViewData& rViewData = GetViewData();
1473 ScDocument& rDoc = rViewData.GetDocument();
1474 ScDocShell* pDocSh = rViewData.GetDocShell();
1475 ScMarkData aMark(rViewData.GetMarkData());
1476 const ScAddress& rCurPos = rViewData.GetCurPos();
1477 ScClipParam& rClipParam = pClipDoc->GetClipParam();
1478 SCCOL nColSize = rClipParam.getPasteColSize();
1479 SCROW nRowSize = rClipParam.getPasteRowSize(*pClipDoc, /*bIncludeFiltered*/false);
1480
1481 if (bTranspose)
1482 {
1483 if (static_cast<SCROW>(rCurPos.Col()) + nRowSize-1 > static_cast<SCROW>(pClipDoc->MaxCol()))
1484 {
1485 ErrorMessage(STR_PASTE_FULL);
1486 return false;
1487 }
1488
1490 pClipDoc->TransposeClip(pTransClip.get(), nFlags, bAsLink, /*bIncludeFiltered*/false);
1491 pClipDoc = pTransClip.release();
1492 SCCOL nTempColSize = nColSize;
1493 nColSize = static_cast<SCCOL>(nRowSize);
1494 nRowSize = static_cast<SCROW>(nTempColSize);
1495 }
1496
1497 if (!rDoc.ValidCol(rCurPos.Col()+nColSize-1) || !rDoc.ValidRow(rCurPos.Row()+nRowSize-1))
1498 {
1499 ErrorMessage(STR_PASTE_FULL);
1500 return false;
1501 }
1502
1503 // Determine the first and last selected sheet numbers.
1504 SCTAB nTab1 = aMark.GetFirstSelected();
1505 SCTAB nTab2 = aMark.GetLastSelected();
1506
1507 ScDocShellModificator aModificator(*pDocSh);
1508
1509 // For multi-selection paste, we don't support cell duplication for larger
1510 // destination range. In case the destination is marked, we reset it to
1511 // the clip size.
1512 ScRange aMarkedRange(rCurPos.Col(), rCurPos.Row(), nTab1,
1513 rCurPos.Col()+nColSize-1, rCurPos.Row()+nRowSize-1, nTab2);
1514
1515 // Extend the marked range to account for filtered rows in the destination
1516 // area.
1517 if (ScViewUtil::HasFiltered(aMarkedRange, rDoc))
1518 {
1519 if (!ScViewUtil::FitToUnfilteredRows(aMarkedRange, rDoc, nRowSize))
1520 return false;
1521 }
1522
1523 bool bAskIfNotEmpty =
1524 bAllowDialogs && (nFlags & InsertDeleteFlags::CONTENTS) &&
1525 nFunction == ScPasteFunc::NONE && SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1526
1527 if (bAskIfNotEmpty)
1528 {
1529 ScRangeList aTestRanges(aMarkedRange);
1530 if (!checkDestRangeForOverwrite(aTestRanges, rDoc, aMark, GetViewData().GetDialogParent()))
1531 return false;
1532 }
1533
1534 aMark.SetMarkArea(aMarkedRange);
1535 MarkRange(aMarkedRange);
1536
1537 bool bInsertCells = (eMoveMode != INS_NONE);
1538 if (bInsertCells)
1539 {
1540 if (!InsertCells(eMoveMode, rDoc.IsUndoEnabled(), true))
1541 return false;
1542 }
1543
1544 // TODO: position this call better for performance.
1546
1547 bool bRowInfo = ( aMarkedRange.aStart.Col()==0 && aMarkedRange.aEnd.Col()==pClipDoc->MaxCol() );
1548 ScDocumentUniquePtr pUndoDoc;
1549 if (rDoc.IsUndoEnabled())
1550 {
1551 pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1552 pUndoDoc->InitUndoSelected(rDoc, aMark, false, bRowInfo);
1553 rDoc.CopyToDocument(aMarkedRange, nUndoFlags, false, *pUndoDoc, &aMark);
1554 }
1555
1556 ScDocumentUniquePtr pMixDoc;
1557 if ( bSkipEmptyCells || nFunction != ScPasteFunc::NONE)
1558 {
1559 if ( nFlags & InsertDeleteFlags::CONTENTS )
1560 {
1561 pMixDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1562 pMixDoc->InitUndoSelected(rDoc, aMark);
1563 rDoc.CopyToDocument(aMarkedRange, InsertDeleteFlags::CONTENTS, false, *pMixDoc, &aMark);
1564 }
1565 }
1566
1567 /* Make draw layer and start drawing undo.
1568 - Needed before AdjustBlockHeight to track moved drawing objects.
1569 - Needed before rDoc.CopyFromClip to track inserted note caption objects.
1570 */
1571 if (nFlags & InsertDeleteFlags::OBJECTS)
1572 pDocSh->MakeDrawLayer();
1573 if (rDoc.IsUndoEnabled())
1574 rDoc.BeginDrawUndo();
1575
1576 InsertDeleteFlags nCopyFlags = nFlags & ~InsertDeleteFlags::OBJECTS;
1577 // in case of transpose, links were added in TransposeClip()
1578 if (bAsLink && bTranspose)
1579 nCopyFlags |= InsertDeleteFlags::FORMULA;
1580 rDoc.CopyMultiRangeFromClip(rCurPos, aMark, nCopyFlags, pClipDoc, true, bAsLink && !bTranspose,
1581 /*bIncludeFiltered*/false, bSkipEmptyCells);
1582
1583 if (pMixDoc)
1584 rDoc.MixDocument(aMarkedRange, nFunction, bSkipEmptyCells, *pMixDoc);
1585
1586 AdjustBlockHeight(); // update row heights before pasting objects
1587
1588 if (nFlags & InsertDeleteFlags::OBJECTS)
1589 {
1590 // Paste the drawing objects after the row heights have been updated.
1591 rDoc.CopyMultiRangeFromClip(rCurPos, aMark, InsertDeleteFlags::OBJECTS, pClipDoc, true,
1592 false, /*bIncludeFiltered*/false, true);
1593 }
1594
1595 if (bRowInfo)
1596 pDocSh->PostPaint(aMarkedRange.aStart.Col(), aMarkedRange.aStart.Row(), nTab1, pClipDoc->MaxCol(), pClipDoc->MaxRow(), nTab1, PaintPartFlags::Grid|PaintPartFlags::Left);
1597 else
1598 {
1599 ScRange aTmp = aMarkedRange;
1600 aTmp.aStart.SetTab(nTab1);
1601 aTmp.aEnd.SetTab(nTab1);
1602 pDocSh->PostPaint(aTmp, PaintPartFlags::Grid);
1603 }
1604
1605 if (rDoc.IsUndoEnabled())
1606 {
1607 SfxUndoManager* pUndoMgr = pDocSh->GetUndoManager();
1608 OUString aUndo = ScResId(
1609 pClipDoc->IsCutMode() ? STR_UNDO_CUT : STR_UNDO_COPY);
1610 pUndoMgr->EnterListAction(aUndo, aUndo, 0, GetViewData().GetViewShell()->GetViewShellId());
1611
1612 ScUndoPasteOptions aOptions; // store options for repeat
1613 aOptions.nFunction = nFunction;
1614 aOptions.bSkipEmptyCells = bSkipEmptyCells;
1615 aOptions.bTranspose = bTranspose;
1616 aOptions.bAsLink = bAsLink;
1617 aOptions.eMoveMode = eMoveMode;
1618
1619 std::unique_ptr<ScUndoPaste> pUndo(new ScUndoPaste(pDocSh,
1620 aMarkedRange, aMark, std::move(pUndoDoc), nullptr, nFlags|nUndoFlags, nullptr, false, &aOptions));
1621
1622 if (bInsertCells)
1623 pUndoMgr->AddUndoAction(std::make_unique<ScUndoWrapper>(std::move(pUndo)), true);
1624 else
1625 pUndoMgr->AddUndoAction(std::move(pUndo));
1626
1627 pUndoMgr->LeaveListAction();
1628 }
1629
1630 aModificator.SetDocumentModified();
1631 PostPasteFromClip(aMarkedRange, aMark);
1632 return true;
1633}
1634
1636 InsertDeleteFlags nFlags, ScDocument* pClipDoc, ScPasteFunc nFunction,
1637 bool bSkipEmptyCells, bool bTranspose, bool bAsLink, bool bAllowDialogs,
1638 InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags )
1639{
1640 if (bTranspose)
1641 {
1642 // We don't allow transpose for this yet.
1643 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
1644 return false;
1645 }
1646
1647 if (eMoveMode != INS_NONE)
1648 {
1649 // We don't allow insertion mode either. Too complicated.
1650 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
1651 return false;
1652 }
1653
1654 ScViewData& rViewData = GetViewData();
1655 ScClipParam& rClipParam = pClipDoc->GetClipParam();
1656 if (rClipParam.mbCutMode)
1657 {
1658 // No cut and paste with this, please.
1659 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
1660 return false;
1661 }
1662
1663 const ScAddress& rCurPos = rViewData.GetCurPos();
1664 ScDocument& rDoc = rViewData.GetDocument();
1665
1666 ScRange aSrcRange = rClipParam.getWholeRange();
1667 SCROW nRowSize = aSrcRange.aEnd.Row() - aSrcRange.aStart.Row() + 1;
1668 SCCOL nColSize = aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1;
1669
1670 if (!rDoc.ValidCol(rCurPos.Col()+nColSize-1) || !rDoc.ValidRow(rCurPos.Row()+nRowSize-1))
1671 {
1672 ErrorMessage(STR_PASTE_FULL);
1673 return false;
1674 }
1675
1676 ScMarkData aMark(rViewData.GetMarkData());
1677
1678 ScRangeList aRanges;
1679 aMark.MarkToSimple();
1680 aMark.FillRangeListWithMarks(&aRanges, false);
1681 if (!ScClipUtil::CheckDestRanges(rDoc, nColSize, nRowSize, aMark, aRanges))
1682 {
1683 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
1684 return false;
1685 }
1686
1687 ScDocShell* pDocSh = rViewData.GetDocShell();
1688
1689 ScDocShellModificator aModificator(*pDocSh);
1690
1691 bool bAskIfNotEmpty =
1692 bAllowDialogs && (nFlags & InsertDeleteFlags::CONTENTS) &&
1693 nFunction == ScPasteFunc::NONE && SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1694
1695 if (bAskIfNotEmpty)
1696 {
1697 if (!checkDestRangeForOverwrite(aRanges, rDoc, aMark, GetViewData().GetDialogParent()))
1698 return false;
1699 }
1700
1701 // TODO: position this call better for performance.
1703
1704 ScDocumentUniquePtr pUndoDoc;
1705 if (rDoc.IsUndoEnabled())
1706 {
1707 pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1708 pUndoDoc->InitUndoSelected(rDoc, aMark);
1709 for (size_t i = 0, n = aRanges.size(); i < n; ++i)
1710 {
1711 rDoc.CopyToDocument(
1712 aRanges[i], nUndoFlags, false, *pUndoDoc, &aMark);
1713 }
1714 }
1715
1716 ScDocumentUniquePtr pMixDoc;
1717 if (bSkipEmptyCells || nFunction != ScPasteFunc::NONE)
1718 {
1719 if (nFlags & InsertDeleteFlags::CONTENTS)
1720 {
1721 pMixDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1722 pMixDoc->InitUndoSelected(rDoc, aMark);
1723 for (size_t i = 0, n = aRanges.size(); i < n; ++i)
1724 {
1725 rDoc.CopyToDocument(
1726 aRanges[i], InsertDeleteFlags::CONTENTS, false, *pMixDoc, &aMark);
1727 }
1728 }
1729 }
1730
1731 if (nFlags & InsertDeleteFlags::OBJECTS)
1732 pDocSh->MakeDrawLayer();
1733 if (rDoc.IsUndoEnabled())
1734 rDoc.BeginDrawUndo();
1735
1736 // First, paste everything but the drawing objects.
1737 for (size_t i = 0, n = aRanges.size(); i < n; ++i)
1738 {
1739 rDoc.CopyFromClip(
1740 aRanges[i], aMark, (nFlags & ~InsertDeleteFlags::OBJECTS), nullptr, pClipDoc,
1741 false, false, true, bSkipEmptyCells);
1742 }
1743
1744 if (pMixDoc)
1745 {
1746 for (size_t i = 0, n = aRanges.size(); i < n; ++i)
1747 rDoc.MixDocument(aRanges[i], nFunction, bSkipEmptyCells, *pMixDoc);
1748 }
1749
1750 AdjustBlockHeight(); // update row heights before pasting objects
1751
1752 // Then paste the objects.
1753 if (nFlags & InsertDeleteFlags::OBJECTS)
1754 {
1755 for (size_t i = 0, n = aRanges.size(); i < n; ++i)
1756 {
1757 rDoc.CopyFromClip(
1758 aRanges[i], aMark, InsertDeleteFlags::OBJECTS, nullptr, pClipDoc,
1759 false, false, true, bSkipEmptyCells);
1760 }
1761 }
1762
1763 // Refresh the range that includes all pasted ranges. We only need to
1764 // refresh the current sheet.
1766 bool bRowInfo = (aSrcRange.aStart.Col()==0 && aSrcRange.aEnd.Col()==pClipDoc->MaxCol());
1767 if (bRowInfo)
1768 nPaint |= PaintPartFlags::Left;
1769 pDocSh->PostPaint(aRanges, nPaint);
1770
1771 if (rDoc.IsUndoEnabled())
1772 {
1773 SfxUndoManager* pUndoMgr = pDocSh->GetUndoManager();
1774 OUString aUndo = ScResId(
1775 pClipDoc->IsCutMode() ? STR_UNDO_CUT : STR_UNDO_COPY);
1776 pUndoMgr->EnterListAction(aUndo, aUndo, 0, GetViewData().GetViewShell()->GetViewShellId());
1777
1778 ScUndoPasteOptions aOptions; // store options for repeat
1779 aOptions.nFunction = nFunction;
1780 aOptions.bSkipEmptyCells = bSkipEmptyCells;
1781 aOptions.bTranspose = bTranspose;
1782 aOptions.bAsLink = bAsLink;
1783 aOptions.eMoveMode = eMoveMode;
1784
1785
1786 pUndoMgr->AddUndoAction(
1787 std::make_unique<ScUndoPaste>(
1788 pDocSh, aRanges, aMark, std::move(pUndoDoc), nullptr, nFlags|nUndoFlags, nullptr, false, &aOptions));
1789 pUndoMgr->LeaveListAction();
1790 }
1791
1792 aModificator.SetDocumentModified();
1793 PostPasteFromClip(aRanges, aMark);
1794
1795 return false;
1796}
1797
1798void ScViewFunc::PostPasteFromClip(const ScRangeList& rPasteRanges, const ScMarkData& rMark)
1799{
1800 ScViewData& rViewData = GetViewData();
1801 ScDocShell* pDocSh = rViewData.GetDocShell();
1802 pDocSh->UpdateOle(rViewData);
1803
1804 SelectionChanged(true);
1805
1807 if (!pModelObj)
1808 return;
1809
1810 ScRangeList aChangeRanges;
1811 for (size_t i = 0, n = rPasteRanges.size(); i < n; ++i)
1812 {
1813 const ScRange& r = rPasteRanges[i];
1814 for (const auto& rTab : rMark)
1815 {
1816 ScRange aChangeRange(r);
1817 aChangeRange.aStart.SetTab(rTab);
1818 aChangeRange.aEnd.SetTab(rTab);
1819 aChangeRanges.push_back(aChangeRange);
1820 }
1821 }
1822 HelperNotifyChanges::Notify(*pModelObj, aChangeRanges);
1823}
1824
1825// D R A G A N D D R O P
1826
1827// inside the doc
1828
1829bool ScViewFunc::MoveBlockTo( const ScRange& rSource, const ScAddress& rDestPos,
1830 bool bCut )
1831{
1832 ScDocShell* pDocSh = GetViewData().GetDocShell();
1834
1836
1837 bool bSuccess = true;
1838 SCTAB nDestTab = rDestPos.Tab();
1839 const ScMarkData& rMark = GetViewData().GetMarkData();
1840 if ( rSource.aStart.Tab() == nDestTab && rSource.aEnd.Tab() == nDestTab && rMark.GetSelectCount() > 1 )
1841 {
1842 // moving within one table and several tables selected -> apply to all selected tables
1843
1844 OUString aUndo = ScResId( bCut ? STR_UNDO_MOVE : STR_UNDO_COPY );
1845 pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo, 0, GetViewData().GetViewShell()->GetViewShellId() );
1846
1847 // collect ranges of consecutive selected tables
1848
1849 ScRange aLocalSource = rSource;
1850 ScAddress aLocalDest = rDestPos;
1851 SCTAB nTabCount = pDocSh->GetDocument().GetTableCount();
1852 SCTAB nStartTab = 0;
1853 while ( nStartTab < nTabCount && bSuccess )
1854 {
1855 while ( nStartTab < nTabCount && !rMark.GetTableSelect(nStartTab) )
1856 ++nStartTab;
1857 if ( nStartTab < nTabCount )
1858 {
1859 SCTAB nEndTab = nStartTab;
1860 while ( nEndTab+1 < nTabCount && rMark.GetTableSelect(nEndTab+1) )
1861 ++nEndTab;
1862
1863 aLocalSource.aStart.SetTab( nStartTab );
1864 aLocalSource.aEnd.SetTab( nEndTab );
1865 aLocalDest.SetTab( nStartTab );
1866
1867 bSuccess = pDocSh->GetDocFunc().MoveBlock(
1868 aLocalSource, aLocalDest, bCut, true/*bRecord*/, true/*bPaint*/, true/*bApi*/ );
1869
1870 nStartTab = nEndTab + 1;
1871 }
1872 }
1873
1874 pDocSh->GetUndoManager()->LeaveListAction();
1875 }
1876 else
1877 {
1878 // move the block as specified
1879 bSuccess = pDocSh->GetDocFunc().MoveBlock(
1880 rSource, rDestPos, bCut, true/*bRecord*/, true/*bPaint*/, true/*bApi*/ );
1881 }
1882
1884 if (bSuccess)
1885 {
1886 // mark destination range
1887 ScAddress aDestEnd(
1888 rDestPos.Col() + rSource.aEnd.Col() - rSource.aStart.Col(),
1889 rDestPos.Row() + rSource.aEnd.Row() - rSource.aStart.Row(),
1890 nDestTab );
1891
1892 bool bIncludeFiltered = bCut;
1893 if ( !bIncludeFiltered )
1894 {
1895 // find number of non-filtered rows
1896 SCROW nPastedCount = pDocSh->GetDocument().CountNonFilteredRows(
1897 rSource.aStart.Row(), rSource.aEnd.Row(), rSource.aStart.Tab());
1898
1899 if ( nPastedCount == 0 )
1900 nPastedCount = 1;
1901 aDestEnd.SetRow( rDestPos.Row() + nPastedCount - 1 );
1902 }
1903
1904 MarkRange( ScRange( rDestPos, aDestEnd ), false );
1905
1906 pDocSh->UpdateOle(GetViewData());
1908 }
1909 return bSuccess;
1910}
1911
1912// link inside the doc
1913
1914bool ScViewFunc::LinkBlock( const ScRange& rSource, const ScAddress& rDestPos )
1915{
1916 // check overlapping
1917
1918 if ( rSource.aStart.Tab() == rDestPos.Tab() )
1919 {
1920 SCCOL nDestEndCol = rDestPos.Col() + ( rSource.aEnd.Col() - rSource.aStart.Col() );
1921 SCROW nDestEndRow = rDestPos.Row() + ( rSource.aEnd.Row() - rSource.aStart.Row() );
1922
1923 if ( rSource.aStart.Col() <= nDestEndCol && rDestPos.Col() <= rSource.aEnd.Col() &&
1924 rSource.aStart.Row() <= nDestEndRow && rDestPos.Row() <= rSource.aEnd.Row() )
1925 {
1926 return false;
1927 }
1928 }
1929
1930 // run with paste
1931
1934 rDoc.CopyTabToClip( rSource.aStart.Col(), rSource.aStart.Row(),
1935 rSource.aEnd.Col(), rSource.aEnd.Row(),
1936 rSource.aStart.Tab(), pClipDoc.get() );
1937
1938 // mark destination area (set cursor, no marks)
1939
1940 if ( GetViewData().GetTabNo() != rDestPos.Tab() )
1941 SetTabNo( rDestPos.Tab() );
1942
1943 MoveCursorAbs( rDestPos.Col(), rDestPos.Row(), SC_FOLLOW_NONE, false, false );
1944
1945 // Paste
1946
1947 PasteFromClip( InsertDeleteFlags::ALL, pClipDoc.get(), ScPasteFunc::NONE, false, false, true ); // as a link
1948
1949 return true;
1950}
1951
1953 SCROW nStartRow , SCCOL nStartCol ,
1954 SCROW nEndRow , SCCOL nEndCol ,
1955 std::vector<std::unique_ptr<ScDataFormFragment>>& rEdits,
1956 sal_uInt16 aColLength )
1957{
1959 ScDocShell* pDocSh = GetViewData().GetDocShell();
1960 ScMarkData& rMark = GetViewData().GetMarkData();
1961 ScDocShellModificator aModificator( *pDocSh );
1962 SfxUndoManager* pUndoMgr = pDocSh->GetUndoManager();
1963
1964 const bool bRecord( rDoc.IsUndoEnabled());
1965 ScDocumentUniquePtr pUndoDoc;
1966 ScDocumentUniquePtr pRedoDoc;
1967 std::unique_ptr<ScRefUndoData> pUndoData;
1968 SCTAB nTab = GetViewData().GetTabNo();
1969 SCTAB nStartTab = nTab;
1970 SCTAB nEndTab = nTab;
1971
1972 {
1973 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
1974 if ( pChangeTrack )
1975 pChangeTrack->ResetLastCut(); // no more cut-mode
1976 }
1977 ScRange aUserRange( nStartCol, nCurrentRow, nStartTab, nEndCol, nCurrentRow, nEndTab );
1978 bool bColInfo = ( nStartRow==0 && nEndRow==rDoc.MaxRow() );
1979 bool bRowInfo = ( nStartCol==0 && nEndCol==rDoc.MaxCol() );
1980 SCCOL nUndoEndCol = nStartCol+aColLength-1;
1981 SCROW nUndoEndRow = nCurrentRow;
1982
1983 if ( bRecord )
1984 {
1985 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1986 pUndoDoc->InitUndoSelected( rDoc , rMark , bColInfo , bRowInfo );
1987 rDoc.CopyToDocument( aUserRange , InsertDeleteFlags::VALUE , false, *pUndoDoc );
1988 }
1989 sal_uInt16 nExtFlags = 0;
1990 pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab , nEndCol, nEndRow, nEndTab ); // content before the change
1991 rDoc.BeginDrawUndo();
1992
1993 for(sal_uInt16 i = 0; i < aColLength; i++)
1994 {
1995 if (rEdits[i] != nullptr)
1996 {
1997 OUString aFieldName = rEdits[i]->m_xEdit->get_text();
1998 rDoc.SetString( nStartCol + i, nCurrentRow, nTab, aFieldName );
1999 }
2000 }
2001 pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nCurrentRow, nStartTab, nEndCol, nCurrentRow, nEndTab ); // content after the change
2002 std::unique_ptr<SfxUndoAction> pUndo( new ScUndoDataForm( pDocSh,
2003 nStartCol, nCurrentRow, nStartTab,
2004 nUndoEndCol, nUndoEndRow, nEndTab, rMark,
2005 std::move(pUndoDoc), std::move(pRedoDoc),
2006 std::move(pUndoData) ) );
2007 pUndoMgr->AddUndoAction( std::make_unique<ScUndoWrapper>( std::move(pUndo) ), true );
2008
2010 if (bColInfo)
2011 {
2012 nPaint |= PaintPartFlags::Top;
2013 nUndoEndCol = rDoc.MaxCol(); // just for drawing !
2014 }
2015 if (bRowInfo)
2016 {
2017 nPaint |= PaintPartFlags::Left;
2018 nUndoEndRow = rDoc.MaxRow(); // just for drawing !
2019 }
2020
2021 pDocSh->PostPaint(
2022 ScRange(nStartCol, nCurrentRow, nStartTab, nUndoEndCol, nUndoEndRow, nEndTab),
2023 nPaint, nExtFlags);
2024 pDocSh->UpdateOle(GetViewData());
2025}
2026
2027/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::std::vector< ScRangeList > ScRangeListVector
Definition: charthelper.hxx:29
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
OUString GetURLNoPass(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
SCTAB Tab() const
Definition: address.hxx:283
void SetCol(SCCOL nColP)
Definition: address.hxx:291
SCROW Row() const
Definition: address.hxx:274
void SetRow(SCROW nRowP)
Definition: address.hxx:287
void SetTab(SCTAB nTabP)
Definition: address.hxx:295
OUString GetColRowString() const
Create a human-readable string representation of the cell address.
Definition: address.cxx:2467
SCCOL Col() const
Definition: address.hxx:279
void ResetLastCut()
Definition: chgtrack.hxx:1048
static void CreateProtectedChartListenersAndNotify(ScDocument &rDoc, const SdrPage *pPage, ScModelObj *pModelObj, SCTAB nTab, const ScRangeListVector &rRangesVector, const ::std::vector< OUString > &rExcludedChartNames, bool bSameDoc=true)
static void GetChartNames(::std::vector< OUString > &rChartNames, const SdrPage *pPage)
static void FillProtectedChartRangesVector(ScRangeListVector &rRangesVector, const ScDocument &rDocument, const SdrPage *pPage)
Stores options which are only relevant for clipboard documents.
Definition: clipoptions.hxx:22
const ScPatternAttr * GetNext(SCCOL &rCol, SCROW &rRow1, SCROW &rRow2)
Definition: dociter.cxx:1584
bool MoveBlock(const ScRange &rSource, const ScAddress &rDestPos, bool bCut, bool bRecord, bool bPaint, bool bApi)
Definition: docfunc.cxx:2852
bool UnmergeCells(const ScRange &rRange, bool bRecord, ScUndoRemoveMerge *pUndoRemoveMerge)
Definition: docfunc.cxx:5050
Create before modifications of the document and destroy thereafter.
Definition: docsh.hxx:457
void SetDocumentModified()
Definition: docsh.cxx:3299
const ScDocument & GetDocument() const
Definition: docsh.hxx:220
void UpdatePaintExt(sal_uInt16 &rExtFlags, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab)
Definition: docsh3.cxx:228
ScDrawLayer * MakeDrawLayer()
Definition: docsh2.cxx:172
void UpdateOle(const ScViewData &rViewData, bool bSnapSize=false)
Definition: docsh6.cxx:152
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
Definition: docsh3.cxx:101
virtual SfxUndoManager * GetUndoManager() override
Definition: docsh.cxx:2947
ScDocFunc & GetDocFunc()
Definition: docsh.hxx:222
SCROW CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:4610
SC_DLLPUBLIC void CopyFromClip(const ScRange &rDestRange, const ScMarkData &rMark, InsertDeleteFlags nInsFlag, ScDocument *pRefUndoDoc, ScDocument *pClipDoc, bool bResetCut=true, bool bAsLink=false, bool bIncludeFiltered=true, bool bSkipEmptyCells=false, const ScRangeList *pDestRanges=nullptr)
Paste data from a clipboard document into this document.
Definition: document.cxx:2851
bool RefreshAutoFilter(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab)
Definition: document.cxx:5779
bool ValidRow(SCROW nRow) const
Definition: document.hxx:899
SC_DLLPUBLIC void CopyUpdated(ScDocument *pPosDoc, ScDocument *pDestDoc)
From this document this method copies the cells of positions at which there are also cells in pPosDoc...
Definition: documen3.cxx:809
SC_DLLPUBLIC bool ExtendMerge(SCCOL nStartCol, SCROW nStartRow, SCCOL &rEndCol, SCROW &rEndRow, SCTAB nTab, bool bRefresh=false)
Definition: document.cxx:5675
ScClipParam & GetClipParam()
Definition: document.cxx:2600
void BeginDrawUndo()
Definition: documen9.cxx:60
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:891
bool IsCutMode()
Definition: document.cxx:2060
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:892
bool HasClipFilteredRows()
Definition: document.cxx:3246
SC_DLLPUBLIC void TransposeClip(ScDocument *pTransClip, InsertDeleteFlags nFlags, bool bAsLink, bool bIncludeFiltered)
Definition: document.cxx:2325
SC_DLLPUBLIC void DeleteSelection(InsertDeleteFlags nDelFlag, const ScMarkData &rMark, bool bBroadcast=true)
Definition: document.cxx:6040
bool HasOLEObjectsInArea(const ScRange &rRange, const ScMarkData *pTabMark=nullptr)
Definition: documen9.cxx:276
SC_DLLPUBLIC void CopyToClip(const ScClipParam &rClipParam, ScDocument *pClipDoc, const ScMarkData *pMarks, bool bKeepScenarioFlags, bool bIncludeObjects)
Definition: document.cxx:2172
SC_DLLPUBLIC bool SetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rString, const ScSetStringParam *pParam=nullptr)
Definition: document.cxx:3421
sal_uInt32 GetDocumentID() const
an ID unique to each document instance
Definition: documen2.cxx:268
void DeleteObjectsInSelection(const ScMarkData &rMark)
Definition: documen9.cxx:268
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1082
void ExtendMergeSel(SCCOL nStartCol, SCROW nStartRow, SCCOL &rEndCol, SCROW &rEndRow, const ScMarkData &rMark, bool bRefresh=false)
Definition: document.cxx:5647
void CopyToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, InsertDeleteFlags nFlags, bool bMarked, ScDocument &rDestDoc, const ScMarkData *pMarks=nullptr, bool bColRowFlags=true)
Definition: document.cxx:2071
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1081
void GetClipArea(SCCOL &nClipX, SCROW &nClipY, bool bIncludeFiltered)
Definition: document.cxx:3177
bool ValidCol(SCCOL nCol) const
Definition: document.hxx:898
SC_DLLPUBLIC void ExtendOverlapped(SCCOL &rStartCol, SCROW &rStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:5585
void SetClipOptions(std::unique_ptr< ScClipOptions > pClipOptions)
Definition: documen3.cxx:2037
void SetCutMode(bool bCut)
Definition: document.cxx:2050
void CopyTabToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, ScDocument *pClipDoc)
Definition: document.cxx:2271
ScChangeTrack * GetChangeTrack() const
Definition: document.hxx:2487
SC_DLLPUBLIC bool HasTable(SCTAB nTab) const
Definition: document.cxx:194
bool IsBlockEmpty(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:5404
bool IsUndoEnabled() const
Definition: document.hxx:1593
void CopyMultiRangeFromClip(const ScAddress &rDestPos, const ScMarkData &rMark, InsertDeleteFlags nInsFlag, ScDocument *pClipDoc, bool bResetCut=true, bool bAsLink=false, bool bIncludeFiltered=true, bool bSkipAttrForEmpty=false)
Definition: document.cxx:3062
bool HasSelectedBlockMatrixFragment(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScMarkData &rMark) const
Definition: document.cxx:5514
void MixDocument(const ScRange &rRange, ScPasteFunc nFunction, bool bSkipEmpty, ScDocument &rSrcDoc)
Definition: document.cxx:3267
SC_DLLPUBLIC void UpdateTranspose(const ScAddress &rDestPos, ScDocument *pClipDoc, const ScMarkData &rMark, ScDocument *pUndoDoc)
Definition: documen3.cxx:1118
void GetClipStart(SCCOL &nClipX, SCROW &nClipY)
Definition: document.cxx:3229
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:316
static void SetGlobalDrawPersist(SfxObjectShell *pPersist)
Definition: drwlayer.cxx:2657
static ScDrawTransferObj * GetOwnClipboard(const css::uno::Reference< css::datatransfer::XTransferable2 > &)
Definition: drwtrans.cxx:232
SdrModel * GetModel() const
Definition: drwtrans.hxx:78
const OUString & GetShellID() const
Definition: drwtrans.cxx:624
SdrObject * ApplyGraphicToObject(SdrObject &rHitObject, const Graphic &rGraphic, const OUString &rBeginUndoText, const OUString &rFile)
Definition: drawview.cxx:1126
bool IsEditable() const
Definition: editable.hxx:84
TranslateId GetMessageId() const
Definition: editable.cxx:152
static tools::SvRef< ScDocShell > xDrawClipDocShellRef
Definition: global.hxx:592
static void SetClipDocName(const OUString &rNew)
Definition: global.cxx:497
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
const_iterator end() const
Definition: markdata.hxx:164
const ScRange & GetMarkArea() const
Definition: markdata.hxx:83
SCTAB GetFirstSelected() const
Definition: markdata.cxx:185
bool IsMultiMarked() const
Definition: markdata.hxx:81
void FillRangeListWithMarks(ScRangeList *pList, bool bClear, SCTAB nForTab=-1) const
Create a range list of marks.
Definition: markdata.cxx:372
SCTAB GetLastSelected() const
Definition: markdata.cxx:194
bool GetTableSelect(SCTAB nTab) const
Definition: markdata.cxx:169
SCTAB GetSelectCount() const
Definition: markdata.cxx:180
void MarkToMulti()
Definition: markdata.cxx:209
bool IsMarked() const
Definition: markdata.hxx:80
void SetMarkArea(const ScRange &rRange)
Definition: markdata.cxx:92
const_iterator begin() const
Definition: markdata.hxx:163
void MarkToSimple()
Definition: markdata.cxx:222
bool IsMerged() const
Definition: attrib.hxx:71
bool IsOverlapped() const
Definition: attrib.hxx:101
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:72
ScRange & front()
Definition: rangelst.hxx:92
bool empty() const
Definition: rangelst.hxx:88
void push_back(const ScRange &rRange)
Definition: rangelst.cxx:1137
size_t size() const
Definition: rangelst.hxx:89
void GetVars(SCCOL &nCol1, SCROW &nRow1, SCTAB &nTab1, SCCOL &nCol2, SCROW &nRow2, SCTAB &nTab2) const
Definition: address.hxx:690
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
Warning box for "Replace cell contents?".
Definition: warnbox.hxx:27
static void notifyAllViewsSheetGeomInvalidation(const SfxViewShell *pForViewShell, bool bColumns, bool bRows, bool bSizes, bool bHidden, bool bFiltered, bool bGroups, SCTAB nCurrentTabIndex)
Emits a LOK_CALLBACK_INVALIDATE_SHEET_GEOMETRY for all views whose current tab is equal to nCurrentTa...
Definition: tabvwshc.cxx:568
static css::uno::Reference< css::datatransfer::XTransferable2 > GetClipData(vcl::Window *pWin)
Definition: tabvwshc.cxx:494
void DoneBlockMode(bool bContinue=false)
Definition: tabview2.cxx:409
void ErrorMessage(TranslateId pGlobStrId)
Definition: tabview2.cxx:1446
void SelectionChanged(bool bFromPaste=false)
Definition: tabview3.cxx:532
void MarkRange(const ScRange &rRange, bool bSetCursor=true, bool bContinue=false)
Definition: tabview3.cxx:1711
vcl::Window * GetFrameWin() const
Definition: tabview.hxx:585
SC_DLLPUBLIC void MoveCursorAbs(SCCOL nCurX, SCROW nCurY, ScFollowMode eMode, bool bShift, bool bControl, bool bKeepOld=false, bool bKeepSel=false)
Definition: tabview3.cxx:1194
static void UpdateInputLine()
Definition: tabview3.cxx:3059
ScViewData & GetViewData()
Definition: tabview.hxx:335
void ShowAllCursors()
Definition: tabview3.cxx:234
ScGridWindow * GetActiveWin()
Definition: tabview.cxx:877
void ResetAutoSpellForContentChange()
Definition: tabview.cxx:2278
SC_DLLPUBLIC void CellContentChanged()
Definition: tabview3.cxx:513
ScDrawView * GetScDrawView()
Definition: tabview.hxx:343
void MarkDataChanged()
Definition: tabview3.cxx:1770
void InitOwnBlockMode(const ScRange &rMarkRange)
Definition: tabview2.cxx:332
SC_DLLPUBLIC void SetTabNo(SCTAB nTab, bool bNew=false, bool bExtendSelection=false, bool bSameTabButMoved=false)
Definition: tabview3.cxx:1822
void HideAllCursors()
Definition: tabview3.cxx:220
ScDocument * GetDocument() const
Definition: transobj.hxx:80
static SfxObjectShell * SetDrawClipDoc(bool bAnyOle, const std::shared_ptr< ScDocument > &={})
Definition: transobj.cxx:814
static SC_DLLPUBLIC ScTransferObj * GetOwnClipboard(const css::uno::Reference< css::datatransfer::XTransferable2 > &)
Definition: transobj.cxx:199
ScMarkData & GetMarkData()
Definition: viewdata.cxx:3141
SCTAB GetTabNo() const
Definition: viewdata.hxx:395
ScDocument & GetDocument() const
Definition: viewdata.hxx:380
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:354
ScGridWindow * GetActiveWin()
Definition: viewdata.cxx:3157
ScTabViewShell * GetViewShell() const
Definition: viewdata.hxx:357
ScMarkType GetSimpleArea(SCCOL &rStartCol, SCROW &rStartRow, SCTAB &rStartTab, SCCOL &rEndCol, SCROW &rEndRow, SCTAB &rEndTab) const
Definition: viewdata.cxx:1181
ScSplitPos GetActivePart() const
Definition: viewdata.hxx:398
Point GetScrPos(SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich, bool bAllowNeg=false, SCTAB nForTab=-1) const
Definition: viewdata.cxx:2375
bool IsActive() const
Definition: viewdata.hxx:382
ScAddress GetCurPos() const
Definition: viewdata.cxx:4127
SCROW GetCurY() const
Definition: viewdata.hxx:402
SCCOL GetCurX() const
Definition: viewdata.hxx:401
void PasteFromTransferable(const css::uno::Reference< css::datatransfer::XTransferable > &rxTransferable)
Definition: viewfun3.cxx:622
bool CopyToClipMultiRange(const ScDocument *pClipDoc, const ScRangeList &rRanges, bool bCut, bool bApi, bool bIncludeObjects)
Definition: viewfun3.cxx:308
rtl::Reference< ScTransferObj > CopyToTransferable()
Definition: viewfun3.cxx:432
bool InsertCells(InsCellCmd eCmd, bool bRecord=true, bool bPartOfPaste=false)
Definition: viewfunc.cxx:1661
SC_DLLPUBLIC void CutToClip()
Definition: viewfun3.cxx:90
void PostPasteFromClip(const ScRangeList &rPasteRanges, const ScMarkData &rMark)
Definition: viewfun3.cxx:1798
bool PasteFromClipToMultiRanges(InsertDeleteFlags nFlags, ScDocument *pClipDoc, ScPasteFunc nFunction, bool bSkipEmptyCells, bool bTranspose, bool bAsLink, bool bAllowDialogs, InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags)
Definition: viewfun3.cxx:1635
bool PasteMultiRangesFromClip(InsertDeleteFlags nFlags, ScDocument *pClipDoc, ScPasteFunc nFunction, bool bSkipEmptyCells, bool bTranspose, bool bAsLink, bool bAllowDialogs, InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags)
Definition: viewfun3.cxx:1466
SC_DLLPUBLIC void DataFormPutData(SCROW nCurrentRow, SCROW nStartRow, SCCOL nStartCol, SCROW nEndRow, SCCOL nEndCol, std::vector< std::unique_ptr< ScDataFormFragment > > &rEdits, sal_uInt16 aColLength)
Definition: viewfun3.cxx:1952
bool PasteOnDrawObjectLinked(const css::uno::Reference< css::datatransfer::XTransferable > &rxTransferable, SdrObject &rHitObj)
Definition: viewfun3.cxx:769
bool AdjustBlockHeight(bool bPaint=true, ScMarkData *pMarkData=nullptr)
Definition: viewfun2.cxx:115
SC_DLLPUBLIC void PasteFromSystem()
Definition: viewfun3.cxx:485
bool CopyToClipSingleRange(ScDocument *pClipDoc, const ScRangeList &rRanges, bool bCut, bool bIncludeObjects)
Definition: viewfun3.cxx:217
bool PasteDataFormat(SotClipboardFormatId nFormatId, const css::uno::Reference< css::datatransfer::XTransferable > &rxTransferable, SCCOL nPosX, SCROW nPosY, const Point *pLogicPos, bool bLink=false, bool bAllowDialogs=false)
Definition: viewfun5.cxx:78
SC_DLLPUBLIC bool CopyToClip(ScDocument *pClipDoc, bool bCut, bool bApi=false, bool bIncludeObjects=false, bool bStopEdit=true)
Definition: viewfun3.cxx:168
SC_DLLPUBLIC bool PasteFromClip(InsertDeleteFlags nFlags, ScDocument *pClipDoc, ScPasteFunc nFunction=ScPasteFunc::NONE, bool bSkipEmptyCells=false, bool bTranspose=false, bool bAsLink=false, InsCellCmd eMoveMode=INS_NONE, InsertDeleteFlags nUndoExtraFlags=InsertDeleteFlags::NONE, bool bAllowDialogs=false)
Definition: viewfun3.cxx:872
void PasteDraw()
Definition: viewfun3.cxx:468
bool LinkBlock(const ScRange &rSource, const ScAddress &rDestPos)
Definition: viewfun3.cxx:1914
bool MoveBlockTo(const ScRange &rSource, const ScAddress &rDestPos, bool bCut)
Definition: viewfun3.cxx:1829
bool AdjustRowHeight(SCROW nStartRow, SCROW nEndRow, bool bApi)
Definition: viewfun2.cxx:193
static void UnmarkFiltered(ScMarkData &rMark, const ScDocument &rDoc)
Definition: viewutil.cxx:223
static bool FitToUnfilteredRows(ScRange &rRange, const ScDocument &rDoc, size_t nRows)
Fit a range to cover nRows number of unfiltered rows.
Definition: viewutil.cxx:257
static bool HasFiltered(const ScRange &rRange, const ScDocument &rDoc)
Definition: viewutil.cxx:271
const SdrPage * GetPage(sal_uInt16 nPgNum) const
SdrModel * GetModel() const
const INetURLObject & GetURLObject() const
void FillTransferableObjectDescriptor(TransferableObjectDescriptor &rDesc) const
static OUString CreateShellID(const SfxObjectShell *pShell)
SfxMedium * GetMedium() const
css::uno::Reference< css::frame::XModel3 > GetModel() const
OUString GetTitle(sal_uInt16 nMaxLen=0) const
size_t LeaveListAction()
virtual void EnterListAction(const OUString &rComment, const OUString &rRepeatComment, sal_uInt16 nId, ViewShellId nViewShellId)
virtual void AddUndoAction(std::unique_ptr< SfxUndoAction > pAction, bool bTryMerg=false)
static sal_uInt8 GetExchangeAction(const DataFlavorExVector &rDataFlavorExVector, SotExchangeDest nDestination, sal_uInt16 nSourceOptions, sal_uInt8 nUserAction, SotClipboardFormatId &rFormat, sal_uInt8 &rDefaultAction, SotClipboardFormatId nOnlyTestFormat=SotClipboardFormatId::NONE, const css::uno::Reference< css::datatransfer::XTransferable > *pxTransferable=nullptr, SotExchangeActionFlags *pActionFlags=nullptr)
static SotClipboardFormatId RegisterFormatName(const OUString &rName)
bool GetTransferableObjectDescriptor(SotClipboardFormatId nFormat, TransferableObjectDescriptor &rDesc)
const DataFlavorExVector & GetDataFlavorExVector() const
bool GetSotStorageStream(SotClipboardFormatId nFormat, tools::SvRef< SotTempStream > &rStreamRef) const
bool GetGDIMetaFile(SotClipboardFormatId nFormat, GDIMetaFile &rMtf, size_t nMaxActions=0) const
static TransferableDataHelper CreateFromSystemClipboard(vcl::Window *pWindow)
bool HasFormat(SotClipboardFormatId nFormat) const
const css::uno::Reference< css::datatransfer::XTransferable > & GetTransferable() const
bool GetBitmapEx(SotClipboardFormatId nFormat, BitmapEx &rBmp) const
css::uno::Reference< css::datatransfer::XTransferable > GetXTransferable() const
void readGraphic(Graphic &rGraphic)
static UITestLogger & getInstance()
void logEvent(const EventDescription &rDescription)
#define SO3_SWWEB_CLASSID
#define SO3_SW_CLASSID
T * get() const
Point PixelToLogic(const Point &rDevicePt) const
std::unique_ptr< ScDocument, o3tl::default_delete< ScDocument > > ScDocumentUniquePtr
Definition: document.hxx:2717
@ SCDOCMODE_CLIP
Definition: document.hxx:256
@ SCDOCMODE_UNDO
Definition: document.hxx:257
#define EXCHG_OUT_ACTION_INSERT_GDIMETAFILE
#define EXCHG_OUT_ACTION_INSERT_BITMAP
#define EXCHG_INOUT_ACTION_NONE
#define EXCHG_OUT_ACTION_INSERT_GRAPH
#define EXCHG_IN_ACTION_COPY
#define EXCHG_OUT_ACTION_INSERT_SVXB
#define EXCHG_IN_ACTION_DEFAULT
SotClipboardFormatId
ScPasteFunc
Definition: global.hxx:180
InsCellCmd
Definition: global.hxx:289
@ INS_NONE
Definition: global.hxx:294
InsertDeleteFlags
Definition: global.hxx:149
@ NOTE
Strings (and string results if InsertDeleteFlags::FORMULA is not set).
@ NOCAPTIONS
Sparklines in a cell.
@ OBJECTS
Cell styles.
@ ATTRIB
Internal use only (d&d undo): do not delete caption objects of cell notes.
@ FORMULA
Cell notes.
HasAttrFlags
Definition: global.hxx:184
PaintPartFlags
Definition: global.hxx:109
void * p
sal_Int64 n
ScModelObj * getMustPropagateChangesModel(const ScDocShell &rDocShell)
Definition: docsh.hxx:475
void Notify(ScModelObj &rModelObj, const ScRangeList &rChangeRanges, const OUString &rType=OUString("cell-change"), const css::uno::Sequence< css::beans::PropertyValue > &rProperties=css::uno::Sequence< css::beans::PropertyValue >())
Definition: docsh.hxx:483
bool CheckDestRanges(const ScDocument &rDoc, SCCOL nSrcCols, SCROW nSrcRows, const ScMarkData &rMark, const ScRangeList &rDest)
Definition: cliputil.cxx:137
int i
action
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
#define SFX_TITLE_FULLNAME
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
constexpr TypedWhichId< ScMergeFlagAttr > ATTR_MERGE_FLAG(145)
constexpr TypedWhichId< ScMergeAttr > ATTR_MERGE(144)
#define SC_MOD()
Definition: scmod.hxx:249
std::map< OUString, OUString > aParameters
This struct stores general clipboard parameters associated with a ScDocument instance created in clip...
Definition: clipparam.hxx:31
void setSourceDocID(sal_uInt32 nVal)
Definition: clipparam.hxx:73
bool isMultiRange() const
Definition: clipparam.cxx:38
SCCOL getPasteColSize()
Get the column size of a pasted range.
Definition: clipparam.cxx:43
SCROW getPasteRowSize(const ScDocument &rSrcDoc, bool bIncludeFiltered)
Same as the above method, but returns the row size of the compressed range.
Definition: clipparam.cxx:73
sal_uInt32 getSourceDocID() const
Definition: clipparam.hxx:72
ScRangeListVector maProtectedChartRangesVector
Definition: clipparam.hxx:38
Direction meDirection
Definition: clipparam.hxx:35
ScRangeList maRanges
Definition: clipparam.hxx:34
bool mbCutMode
Definition: clipparam.hxx:36
ScRange getWholeRange() const
Return a single range that encompasses all individual ranges.
Definition: clipparam.cxx:109
InsCellCmd eMoveMode
Definition: undoblk.hxx:169
ScPasteFunc nFunction
Definition: undoblk.hxx:165
unsigned char sal_uInt8
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17
RET_NO
RET_YES
ScMarkType
States GetSimpleArea() returns for the underlying selection marks, so the caller can react if the res...
Definition: viewdata.hxx:61
@ SC_MARK_MULTI
Definition: viewdata.hxx:70
@ SC_MARK_SIMPLE
Definition: viewdata.hxx:65
@ SC_MARK_SIMPLE_FILTERED
Definition: viewdata.hxx:67
@ SC_FOLLOW_NONE
Definition: viewdata.hxx:52
static bool lcl_SelHasAttrib(const ScDocument &rDoc, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData &rTabSelection, HasAttrFlags nMask)
Definition: viewfun3.cxx:828