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>
23 #include <comphelper/classids.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>
35 #include <vcl/TypeSerializer.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 
68 using namespace com::sun::star;
69 
70 namespace {
71 
72 void 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 {
92  UpdateInputLine();
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  {
104  ScDocument& rDoc = GetViewData().GetDocument();
105  ScDocShell* pDocSh = GetViewData().GetDocShell();
106  ScMarkData& rMark = GetViewData().GetMarkData();
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  {
113  DoneBlockMode();
114  InitOwnBlockMode( aRange );
115  rMark.SetMarkArea( aRange );
116  MarkDataChanged();
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 
155  CellContentChanged();
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 
168 bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, bool bCut, bool bApi, bool bIncludeObjects, bool bStopEdit )
169 {
170  ScRange aRange;
171  ScMarkType eMarkType = GetViewData().GetSimpleArea( aRange );
172  ScMarkData& rMark = GetViewData().GetMarkData();
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.
201 bool 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 )
206  UpdateInputLine();
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 
217 bool 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;
222  ScDocument& rDoc = GetViewData().GetDocument();
223  ScMarkData& rMark = GetViewData().GetMarkData();
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, aObjDesc ));
298  {
300  pTransferObj->SetDrawPersist( aPersistRef );// keep persist for ole objects alive
301  }
302  pTransferObj->CopyToClipboard( GetActiveWin() );
303  }
304 
305  return true;
306 }
307 
308 bool 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;
327  ScDocument& rDoc = GetViewData().GetDocument();
328  ScMarkData& rMark = GetViewData().GetMarkData();
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), 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  {
437  ScDocument& rDoc = GetViewData().GetDocument();
438  ScMarkData& rMark = GetViewData().GetMarkData();
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), 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 {
487  UpdateInputLine();
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  {
496  PasteFromClip( InsertDeleteFlags::ALL, pOwnClip->GetDocument(),
497  ScPasteFunc::NONE, false, false, false, INS_NONE, InsertDeleteFlags::NONE,
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 
622 void 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(),
629  ScPasteFunc::NONE, false, false, false, INS_NONE, InsertDeleteFlags::NONE,
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 {
715  UpdateInputLine();
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  {
723  PasteFromClip( InsertDeleteFlags::ALL, pOwnClip->GetDocument(),
724  ScPasteFunc::NONE, false, false, false, INS_NONE, InsertDeleteFlags::NONE,
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 
828 static 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 
839 namespace {
840 
841 bool 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 
908  ScMarkData& rMark = GetViewData().GetMarkData();
909  if (rMark.IsMultiMarked())
910  {
911  // Source data is single-range but destination is multi-range.
912  return PasteFromClipToMultiRanges(
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.
954  ResetAutoSpellForContentChange();
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 
971  ScDocument& rDoc = GetViewData().GetDocument();
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 );
1276  MarkDataChanged();
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.
1545  ResetAutoSpellForContentChange();
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.
1702  ResetAutoSpellForContentChange();
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 
1798 void 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 
1829 bool ScViewFunc::MoveBlockTo( const ScRange& rSource, const ScAddress& rDestPos,
1830  bool bCut )
1831 {
1832  ScDocShell* pDocSh = GetViewData().GetDocShell();
1833  HideAllCursors();
1834 
1835  ResetAutoSpellForContentChange();
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 
1883  ShowAllCursors();
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());
1907  SelectionChanged();
1908  }
1909  return bSuccess;
1910 }
1911 
1912 // link inside the doc
1913 
1914 bool 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 
1932  ScDocument& rDoc = GetViewData().GetDocument();
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 {
1958  ScDocument& rDoc = GetViewData().GetDocument();
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: */
SC_DLLPUBLIC void UpdateTranspose(const ScAddress &rDestPos, ScDocument *pClipDoc, const ScMarkData &rMark, ScDocument *pUndoDoc)
Definition: documen3.cxx:1112
ScMarkData & GetMarkData()
Definition: viewdata.cxx:3135
void BeginDrawUndo()
Definition: documen9.cxx:60
#define EXCHG_IN_ACTION_COPY
static ScDrawTransferObj * GetOwnClipboard(const css::uno::Reference< css::datatransfer::XTransferable2 > &)
Definition: drwtrans.cxx:231
OUString GetColRowString() const
Create a human-readable string representation of the cell address.
Definition: address.cxx:2467
bool RefreshAutoFilter(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab)
Definition: document.cxx:5766
static void FillProtectedChartRangesVector(ScRangeListVector &rRangesVector, const ScDocument &rDocument, const SdrPage *pPage)
void MarkToSimple()
Definition: markdata.cxx:222
static SotClipboardFormatId RegisterFormatName(const OUString &rName)
void GetClipStart(SCCOL &nClipX, SCROW &nClipY)
Definition: document.cxx:3221
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:354
ScAddress aStart
Definition: address.hxx:497
bool PasteMultiRangesFromClip(InsertDeleteFlags nFlags, ScDocument *pClipDoc, ScPasteFunc nFunction, bool bSkipEmptyCells, bool bTranspose, bool bAsLink, bool bAllowDialogs, InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags)
Definition: viewfun3.cxx:1466
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:42
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
SC_DLLPUBLIC bool CopyToClip(ScDocument *pClipDoc, bool bCut, bool bApi=false, bool bIncludeObjects=false, bool bStopEdit=true)
Definition: viewfun3.cxx:168
void SetCutMode(bool bCut)
Definition: document.cxx:2042
void readGraphic(Graphic &rGraphic)
HasAttrFlags
Definition: global.hxx:183
bool GetBitmapEx(SotClipboardFormatId nFormat, BitmapEx &rBmp) const
Sparklines in a cell.
SCROW Row() const
Definition: address.hxx:274
OUString GetTitle(sal_uInt16 nMaxLen=0) const
void MarkToMulti()
Definition: markdata.cxx:209
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
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)
SCROW GetCurY() const
Definition: viewdata.hxx:402
SdrModel * GetModel() const
Definition: drwtrans.hxx:78
bool IsOverlapped() const
Definition: attrib.hxx:101
Warning box for "Replace cell contents?".
Definition: warnbox.hxx:26
sal_Int64 n
css::uno::Reference< css::frame::XModel3 > GetModel() const
void FillRangeListWithMarks(ScRangeList *pList, bool bClear, SCTAB nForTab=-1) const
Create a range list of marks.
Definition: markdata.cxx:372
ScRangeListVector maProtectedChartRangesVector
Definition: clipparam.hxx:38
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:3054
#define SO3_SW_CLASSID
SCTAB GetTabNo() const
Definition: viewdata.hxx:395
void setSourceDocID(sal_uInt32 nVal)
Definition: clipparam.hxx:73
ScAddress aEnd
Definition: address.hxx:498
ScSplitPos GetActivePart() const
Definition: viewdata.hxx:398
Direction meDirection
Definition: clipparam.hxx:35
ScDocument & GetDocument() const
Definition: viewdata.hxx:380
static css::uno::Reference< css::datatransfer::XTransferable2 > GetClipData(vcl::Window *pWin)
Definition: tabvwshc.cxx:494
Stores options which are only relevant for clipboard documents.
Definition: clipoptions.hxx:21
void SetClipOptions(std::unique_ptr< ScClipOptions > pClipOptions)
Definition: documen3.cxx:2031
void FillTransferableObjectDescriptor(TransferableObjectDescriptor &rDesc) const
bool HasFormat(SotClipboardFormatId nFormat) const
void GetClipArea(SCCOL &nClipX, SCROW &nClipY, bool bIncludeFiltered)
Definition: document.cxx:3169
SC_DLLPUBLIC bool HasAttrib(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, HasAttrFlags nMask) const
Definition: document.cxx:5264
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 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 void CreateProtectedChartListenersAndNotify(ScDocument &rDoc, const SdrPage *pPage, ScModelObj *pModelObj, SCTAB nTab, const ScRangeListVector &rRangesVector, const ::std::vector< OUString > &rExcludedChartNames, bool bSameDoc=true)
constexpr TypedWhichId< ScMergeAttr > ATTR_MERGE(144)
const ScRange & GetMarkArea() const
Definition: markdata.hxx:83
SCCOL getPasteColSize()
Get the column size of a pasted range.
Definition: clipparam.cxx:43
void MixDocument(const ScRange &rRange, ScPasteFunc nFunction, bool bSkipEmpty, ScDocument &rSrcDoc)
Definition: document.cxx:3259
Internal use only (d&d undo): do not delete caption objects of cell notes.
#define EXCHG_IN_ACTION_DEFAULT
virtual SfxUndoManager * GetUndoManager() override
Definition: docsh.cxx:2932
RET_NO
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:2843
static UITestLogger & getInstance()
void logEvent(const EventDescription &rDescription)
static void SetGlobalDrawPersist(SfxObjectShell *pPersist)
Definition: drwlayer.cxx:2655
RET_YES
SC_DLLPUBLIC void CutToClip()
Not used?
Definition: viewfun3.cxx:90
void PostPasteFromClip(const ScRangeList &rPasteRanges, const ScMarkData &rMark)
Definition: viewfun3.cxx:1798
bool CopyToClipSingleRange(ScDocument *pClipDoc, const ScRangeList &rRanges, bool bCut, bool bIncludeObjects)
Definition: viewfun3.cxx:217
ScClipParam & GetClipParam()
Definition: document.cxx:2592
void UpdatePaintExt(sal_uInt16 &rExtFlags, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab)
Definition: docsh3.cxx:228
bool PasteOnDrawObjectLinked(const css::uno::Reference< css::datatransfer::XTransferable > &rxTransferable, SdrObject &rHitObj)
Definition: viewfun3.cxx:769
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:891
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:315
#define EXCHG_INOUT_ACTION_NONE
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:803
SCTAB GetSelectCount() const
Definition: markdata.cxx:180
bool IsMultiMarked() const
Definition: markdata.hxx:81
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:2063
static TransferableDataHelper CreateFromSystemClipboard(vcl::Window *pWindow)
void push_back(const ScRange &rRange)
Definition: rangelst.cxx:1137
SC_DLLPUBLIC bool HasTable(SCTAB nTab) const
Definition: document.cxx:193
SCTAB Tab() const
Definition: address.hxx:283
bool mbCutMode
Definition: clipparam.hxx:36
#define EXCHG_OUT_ACTION_INSERT_GRAPH
SotClipboardFormatId
ScDocument * GetDocument() const
Definition: transobj.hxx:80
SC_DLLPUBLIC void PasteFromSystem()
Definition: viewfun3.cxx:485
void SetCol(SCCOL nColP)
Definition: address.hxx:291
ScDrawLayer * MakeDrawLayer()
Definition: docsh2.cxx:172
ScChangeTrack * GetChangeTrack() const
Definition: document.hxx:2485
void CopyTabToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, ScDocument *pClipDoc)
Definition: document.cxx:2263
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:72
bool empty() const
Definition: rangelst.hxx:88
ScTabViewShell * GetViewShell() const
Definition: viewdata.hxx:357
bool IsBlockEmpty(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:5391
ScPasteFunc
Definition: global.hxx:179
void SetMarkArea(const ScRange &rRange)
Definition: markdata.cxx:92
SC_DLLPUBLIC bool SetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rString, const ScSetStringParam *pParam=nullptr)
Definition: document.cxx:3413
static void GetChartNames(::std::vector< OUString > &rChartNames, const SdrPage *pPage)
bool HasOLEObjectsInArea(const ScRange &rRange, const ScMarkData *pTabMark=nullptr)
Definition: documen9.cxx:276
void SetTab(SCTAB nTabP)
Definition: address.hxx:295
bool HasClipFilteredRows()
Definition: document.cxx:3238
#define SFX_TITLE_FULLNAME
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1081
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:890
T * get() const
virtual void AddUndoAction(std::unique_ptr< SfxUndoAction > pAction, bool bTryMerg=false)
sal_uInt32 getSourceDocID() const
Definition: clipparam.hxx:72
SCROW CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:4597
static void SetClipDocName(const OUString &rNew)
Definition: global.cxx:493
static bool HasFiltered(const ScRange &rRange, const ScDocument &rDoc)
Definition: viewutil.cxx:271
bool IsMarked() const
Definition: markdata.hxx:80
int i
Point GetScrPos(SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich, bool bAllowNeg=false, SCTAB nForTab=-1) const
Definition: viewdata.cxx:2375
bool LinkBlock(const ScRange &rSource, const ScAddress &rDestPos)
Definition: viewfun3.cxx:1914
bool PasteFromClipToMultiRanges(InsertDeleteFlags nFlags, ScDocument *pClipDoc, ScPasteFunc nFunction, bool bSkipEmptyCells, bool bTranspose, bool bAsLink, bool bAllowDialogs, InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags)
Definition: viewfun3.cxx:1635
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
ScMarkType
States GetSimpleArea() returns for the underlying selection marks, so the caller can react if the res...
Definition: viewdata.hxx:60
std::unique_ptr< ScDocument, o3tl::default_delete< ScDocument > > ScDocumentUniquePtr
Definition: document.hxx:2715
css::uno::Reference< css::datatransfer::XTransferable > GetXTransferable() const
sal_Int16 SCCOL
Definition: types.hxx:21
SC_DLLPUBLIC void DeleteSelection(InsertDeleteFlags nDelFlag, const ScMarkData &rMark, bool bBroadcast=true)
Definition: document.cxx:6027
InsertDeleteFlags
Definition: global.hxx:147
bool ValidCol(SCCOL nCol) const
Definition: document.hxx:897
static tools::SvRef< ScDocShell > xDrawClipDocShellRef
Definition: global.hxx:578
#define SC_MOD()
Definition: scmod.hxx:249
const SdrPage * GetPage(sal_uInt16 nPgNum) const
size_t size() const
Definition: rangelst.hxx:89
static OUString CreateShellID(const SfxObjectShell *pShell)
ScMarkType GetSimpleArea(SCCOL &rStartCol, SCROW &rStartRow, SCTAB &rStartTab, SCCOL &rEndCol, SCROW &rEndRow, SCTAB &rEndTab) const
Definition: viewdata.cxx:1181
bool IsCutMode()
Definition: document.cxx:2052
ScGridWindow * GetActiveWin()
Definition: viewdata.cxx:3151
ScPasteFunc nFunction
Definition: undoblk.hxx:165
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
bool MoveBlockTo(const ScRange &rSource, const ScAddress &rDestPos, bool bCut)
Definition: viewfun3.cxx:1829
bool IsEditable() const
Definition: editable.hxx:84
void GetVars(SCCOL &nCol1, SCROW &nRow1, SCTAB &nTab1, SCCOL &nCol2, SCROW &nRow2, SCTAB &nTab2) const
Definition: address.hxx:690
Point PixelToLogic(const Point &rDevicePt) const
void ResetLastCut()
Definition: chgtrack.hxx:1048
static void UnmarkFiltered(ScMarkData &rMark, const ScDocument &rDoc)
Definition: viewutil.cxx:223
bool HasSelectedBlockMatrixFragment(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScMarkData &rMark) const
Definition: document.cxx:5501
ScRangeList maRanges
Definition: clipparam.hxx:34
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
Definition: docsh3.cxx:101
SC_DLLPUBLIC bool ExtendMerge(SCCOL nStartCol, SCROW nStartRow, SCCOL &rEndCol, SCROW &rEndRow, SCTAB nTab, bool bRefresh=false)
Definition: document.cxx:5662
TranslateId GetMessageId() const
Definition: editable.cxx:152
const_iterator end() const
Definition: markdata.hxx:164
sal_uInt32 GetDocumentID() const
an ID unique to each document instance
Definition: documen2.cxx:266
SCCOL Col() const
Definition: address.hxx:279
size_t LeaveListAction()
ScAddress GetCurPos() const
Definition: viewdata.cxx:4121
bool CopyToClipMultiRange(const ScDocument *pClipDoc, const ScRangeList &rRanges, bool bCut, bool bApi, bool bIncludeObjects)
Definition: viewfun3.cxx:308
bool IsMerged() const
Definition: attrib.hxx:71
ScModelObj * getMustPropagateChangesModel(const ScDocShell &rDocShell)
Definition: docsh.hxx:475
rtl::Reference< ScTransferObj > CopyToTransferable()
Definition: viewfun3.cxx:432
::std::vector< ScRangeList > ScRangeListVector
Definition: charthelper.hxx:29
bool CheckDestRanges(const ScDocument &rDoc, SCCOL nSrcCols, SCROW nSrcRows, const ScMarkData &rMark, const ScRangeList &rDest)
Definition: cliputil.cxx:125
bool UnmergeCells(const ScRange &rRange, bool bRecord, ScUndoRemoveMerge *pUndoRemoveMerge)
Definition: docfunc.cxx:5049
constexpr TypedWhichId< ScMergeFlagAttr > ATTR_MERGE_FLAG(145)
sal_Int32 SCROW
Definition: types.hxx:17
ScRange getWholeRange() const
Return a single range that encompasses all individual ranges.
Definition: clipparam.cxx:109
void UpdateOle(const ScViewData &rViewData, bool bSnapSize=false)
Definition: docsh6.cxx:152
bool ValidRow(SCROW nRow) const
Definition: document.hxx:898
const OUString & GetShellID() const
Definition: drwtrans.cxx:626
bool GetSotStorageStream(SotClipboardFormatId nFormat, tools::SvRef< SotTempStream > &rStreamRef) const
static SfxObjectShell * SetDrawClipDoc(bool bAnyOle, const std::shared_ptr< ScDocument > &={})
Definition: transobj.cxx:816
unsigned char sal_uInt8
void ExtendMergeSel(SCCOL nStartCol, SCROW nStartRow, SCCOL &rEndCol, SCROW &rEndRow, const ScMarkData &rMark, bool bRefresh=false)
Definition: document.cxx:5634
#define EXCHG_OUT_ACTION_INSERT_BITMAP
SC_DLLPUBLIC void TransposeClip(ScDocument *pTransClip, InsertDeleteFlags nFlags, bool bAsLink, bool bIncludeFiltered)
Definition: document.cxx:2317
static bool lcl_SelHasAttrib(const ScDocument &rDoc, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData &rTabSelection, HasAttrFlags nMask)
Definition: viewfun3.cxx:828
bool GetGDIMetaFile(SotClipboardFormatId nFormat, GDIMetaFile &rMtf, size_t nMaxActions=0) const
void PasteFromTransferable(const css::uno::Reference< css::datatransfer::XTransferable > &rxTransferable)
Definition: viewfun3.cxx:622
InsCellCmd
Definition: global.hxx:287
static SC_DLLPUBLIC ScTransferObj * GetOwnClipboard(const css::uno::Reference< css::datatransfer::XTransferable2 > &)
Definition: transobj.cxx:197
const INetURLObject & GetURLObject() const
virtual void EnterListAction(const OUString &rComment, const OUString &rRepeatComment, sal_uInt16 nId, ViewShellId nViewShellId)
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
void * p
#define EXCHG_OUT_ACTION_INSERT_SVXB
const ScPatternAttr * GetNext(SCCOL &rCol, SCROW &rRow1, SCROW &rRow2)
Definition: dociter.cxx:1589
#define SO3_SWWEB_CLASSID
const_iterator begin() const
Definition: markdata.hxx:163
const ScDocument & GetDocument() const
Definition: docsh.hxx:220
void PasteDraw()
Definition: viewfun3.cxx:468
SdrObject * ApplyGraphicToObject(SdrObject &rHitObject, const Graphic &rGraphic, const OUString &rBeginUndoText, const OUString &rFile)
Definition: drawview.cxx:1126
OUString GetURLNoPass(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
void SetDocumentModified()
Definition: docsh.cxx:3284
ScRange & front()
Definition: rangelst.hxx:92
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1080
bool GetTransferableObjectDescriptor(SotClipboardFormatId nFormat, TransferableObjectDescriptor &rDesc)
bool IsUndoEnabled() const
Definition: document.hxx:1590
InsCellCmd eMoveMode
Definition: undoblk.hxx:169
#define EXCHG_OUT_ACTION_INSERT_GDIMETAFILE
ScDocFunc & GetDocFunc()
Definition: docsh.hxx:222
bool MoveBlock(const ScRange &rSource, const ScAddress &rDestPos, bool bCut, bool bRecord, bool bPaint, bool bApi)
Definition: docfunc.cxx:2852
void DeleteObjectsInSelection(const ScMarkData &rMark)
Definition: documen9.cxx:268
bool GetTableSelect(SCTAB nTab) const
Definition: markdata.cxx:169
std::map< OUString, OUString > aParameters
PaintPartFlags
Definition: global.hxx:108
This struct stores general clipboard parameters associated with a ScDocument instance created in clip...
Definition: clipparam.hxx:30
SC_DLLPUBLIC void ExtendOverlapped(SCCOL &rStartCol, SCROW &rStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:5572
const css::uno::Reference< css::datatransfer::XTransferable > & GetTransferable() const
SdrModel * GetModel() const
Strings (and string results if InsertDeleteFlags::FORMULA is not set).
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
Create before modifications of the document and destroy thereafter.
Definition: docsh.hxx:456
sal_Int16 SCTAB
Definition: types.hxx:22
SC_DLLPUBLIC void CopyToClip(const ScClipParam &rClipParam, ScDocument *pClipDoc, const ScMarkData *pMarks, bool bKeepScenarioFlags, bool bIncludeObjects)
Definition: document.cxx:2164
SCCOL GetCurX() const
Definition: viewdata.hxx:401
bool isMultiRange() const
Definition: clipparam.cxx:38
bool m_bDetectedRangeSegmentation false
const DataFlavorExVector & GetDataFlavorExVector() const
SfxMedium * GetMedium() const