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