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