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  ScTransferObj *pOwnClip=nullptr;
623  ScDrawTransferObj *pDrawClip=nullptr;
624  uno::Reference<lang::XUnoTunnel> xTunnel( rxTransferable, uno::UNO_QUERY );
625  if ( xTunnel.is() )
626  {
627  sal_Int64 nHandle = xTunnel->getSomething( ScTransferObj::getUnoTunnelId() );
628  if ( nHandle )
629  pOwnClip = reinterpret_cast<ScTransferObj*>( static_cast<sal_IntPtr>(nHandle));
630  else
631  {
632  nHandle = xTunnel->getSomething( ScDrawTransferObj::getUnoTunnelId() );
633  if ( nHandle )
634  pDrawClip = reinterpret_cast<ScDrawTransferObj*>( static_cast<sal_IntPtr>(nHandle) );
635  }
636  }
637 
638  if (pOwnClip)
639  {
640  PasteFromClip( InsertDeleteFlags::ALL, pOwnClip->GetDocument(),
641  ScPasteFunc::NONE, false, false, false, INS_NONE, InsertDeleteFlags::NONE,
642  true ); // allow warning dialog
643  }
644  else if (pDrawClip)
645  {
646  ScViewData& rViewData = GetViewData();
647  SCCOL nPosX = rViewData.GetCurX();
648  SCROW nPosY = rViewData.GetCurY();
649  vcl::Window* pWin = GetActiveWin();
650  Point aPos = pWin->PixelToLogic( rViewData.GetScrPos( nPosX, nPosY, rViewData.GetActivePart() ) );
651  PasteDraw(
652  aPos, pDrawClip->GetModel(), false,
653  pDrawClip->GetShellID(), SfxObjectShell::CreateShellID(rViewData.GetDocShell()));
654  }
655  else
656  {
657  TransferableDataHelper aDataHelper( rxTransferable );
660  SotClipboardFormatId nFormatId = SotClipboardFormatId::NONE;
661  // first SvDraw-model, then drawing
662  // (only one drawing is allowed)
663 
664  if (aDataHelper.HasFormat( SotClipboardFormatId::DRAWING ))
665  nFormatId = SotClipboardFormatId::DRAWING;
666  else if (aDataHelper.HasFormat( SotClipboardFormatId::SVXB ))
667  nFormatId = SotClipboardFormatId::SVXB;
668  else if (aDataHelper.HasFormat( SotClipboardFormatId::EMBED_SOURCE ))
669  {
670  // If it's a Writer object, insert RTF instead of OLE
671  bool bDoRtf = false;
673  if( aDataHelper.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR, aObjDesc ) )
674  {
675  bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) ||
677  && ( aDataHelper.HasFormat( SotClipboardFormatId::RTF ) || aDataHelper.HasFormat( SotClipboardFormatId::RICHTEXT ) ));
678  }
679  if ( bDoRtf )
680  nFormatId = aDataHelper.HasFormat( SotClipboardFormatId::RTF ) ? SotClipboardFormatId::RTF : SotClipboardFormatId::RICHTEXT;
681  else
682  nFormatId = SotClipboardFormatId::EMBED_SOURCE;
683  }
684  else if (aDataHelper.HasFormat( SotClipboardFormatId::LINK_SOURCE ))
685  nFormatId = SotClipboardFormatId::LINK_SOURCE;
686  // the following format can not affect scenario from #89579#
687  else if (aDataHelper.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ_OLE ))
688  nFormatId = SotClipboardFormatId::EMBEDDED_OBJ_OLE;
689  // SotClipboardFormatId::PRIVATE no longer here (can't work if pOwnClip is NULL)
690  else if (aDataHelper.HasFormat(nBiff8)) // before xxx_OLE formats
691  nFormatId = nBiff8;
692  else if (aDataHelper.HasFormat(nBiff5))
693  nFormatId = nBiff5;
694  else if (aDataHelper.HasFormat(SotClipboardFormatId::RTF))
695  nFormatId = SotClipboardFormatId::RTF;
696  else if (aDataHelper.HasFormat(SotClipboardFormatId::RICHTEXT))
697  nFormatId = SotClipboardFormatId::RICHTEXT;
698  else if (aDataHelper.HasFormat(SotClipboardFormatId::HTML))
699  nFormatId = SotClipboardFormatId::HTML;
700  else if (aDataHelper.HasFormat(SotClipboardFormatId::HTML_SIMPLE))
701  nFormatId = SotClipboardFormatId::HTML_SIMPLE;
702  else if (aDataHelper.HasFormat(SotClipboardFormatId::SYLK))
703  nFormatId = SotClipboardFormatId::SYLK;
704  else if (aDataHelper.HasFormat(SotClipboardFormatId::STRING_TSVC))
705  nFormatId = SotClipboardFormatId::STRING_TSVC;
706  else if (aDataHelper.HasFormat(SotClipboardFormatId::STRING))
707  nFormatId = SotClipboardFormatId::STRING;
708  else if (aDataHelper.HasFormat(SotClipboardFormatId::GDIMETAFILE))
709  nFormatId = SotClipboardFormatId::GDIMETAFILE;
710  else if (aDataHelper.HasFormat(SotClipboardFormatId::BITMAP))
711  nFormatId = SotClipboardFormatId::BITMAP;
712  // xxx_OLE formats come last, like in SotExchange tables
713  else if (aDataHelper.HasFormat( SotClipboardFormatId::EMBED_SOURCE_OLE ))
714  nFormatId = SotClipboardFormatId::EMBED_SOURCE_OLE;
715  else if (aDataHelper.HasFormat( SotClipboardFormatId::LINK_SOURCE_OLE ))
716  nFormatId = SotClipboardFormatId::LINK_SOURCE_OLE;
717  else
718  return;
719 
720  PasteDataFormat( nFormatId, aDataHelper.GetTransferable(),
721  GetViewData().GetCurX(), GetViewData().GetCurY(), nullptr );
722  }
723 }
724 
726 {
727  UpdateInputLine();
728 
729  bool bRet = true;
730  vcl::Window* pWin = GetActiveWin();
731  // keep a reference in case the clipboard is changed during PasteFromClip
733  if ( nFormatId == SotClipboardFormatId::NONE && pOwnClip )
734  {
735  PasteFromClip( InsertDeleteFlags::ALL, pOwnClip->GetDocument(),
736  ScPasteFunc::NONE, false, false, false, INS_NONE, InsertDeleteFlags::NONE,
737  !bApi ); // allow warning dialog
738  }
739  else
740  {
742  if ( !aDataHelper.GetTransferable().is() )
743  return false;
744 
745  SCCOL nPosX = 0;
746  SCROW nPosY = 0;
747 
748  ScViewData& rViewData = GetViewData();
749  ScRange aRange;
750  if ( rViewData.GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
751  {
752  nPosX = aRange.aStart.Col();
753  nPosY = aRange.aStart.Row();
754  }
755  else
756  {
757  nPosX = rViewData.GetCurX();
758  nPosY = rViewData.GetCurY();
759  }
760 
761  bRet = PasteDataFormat( nFormatId, aDataHelper.GetTransferable(),
762  nPosX, nPosY,
763  nullptr, false, !bApi ); // allow warning dialog
764 
765  if ( !bRet && !bApi )
766  ErrorMessage(STR_PASTE_ERROR);
767  }
768  return bRet;
769 }
770 
771 // P A S T E
772 
774  const uno::Reference<datatransfer::XTransferable>& rxTransferable,
775  SdrObject& rHitObj)
776 {
777  TransferableDataHelper aDataHelper( rxTransferable );
778 
779  if ( aDataHelper.HasFormat( SotClipboardFormatId::SVXB ) )
780  {
782  ScDrawView* pScDrawView = GetScDrawView();
783 
784  if( pScDrawView && aDataHelper.GetSotStorageStream( SotClipboardFormatId::SVXB, xStm ) )
785  {
786  Graphic aGraphic;
787  TypeSerializer aSerializer(*xStm);
788  aSerializer.readGraphic(aGraphic);
789 
790  const OUString aBeginUndo(ScResId(STR_UNDO_DRAGDROP));
791 
792  if(pScDrawView->ApplyGraphicToObject( rHitObj, aGraphic, aBeginUndo, "" ))
793  {
794  return true;
795  }
796  }
797  }
798  else if ( aDataHelper.HasFormat( SotClipboardFormatId::GDIMETAFILE ) )
799  {
800  GDIMetaFile aMtf;
801  ScDrawView* pScDrawView = GetScDrawView();
802 
803  if( pScDrawView && aDataHelper.GetGDIMetaFile( SotClipboardFormatId::GDIMETAFILE, aMtf ) )
804  {
805  const OUString aBeginUndo(ScResId(STR_UNDO_DRAGDROP));
806 
807  if(pScDrawView->ApplyGraphicToObject( rHitObj, Graphic(aMtf), aBeginUndo, "" ))
808  {
809  return true;
810  }
811  }
812  }
813  else if ( aDataHelper.HasFormat( SotClipboardFormatId::BITMAP ) || aDataHelper.HasFormat( SotClipboardFormatId::PNG ) )
814  {
815  BitmapEx aBmpEx;
816  ScDrawView* pScDrawView = GetScDrawView();
817 
818  if( pScDrawView && aDataHelper.GetBitmapEx( SotClipboardFormatId::BITMAP, aBmpEx ) )
819  {
820  const OUString aBeginUndo(ScResId(STR_UNDO_DRAGDROP));
821 
822  if(pScDrawView->ApplyGraphicToObject( rHitObj, Graphic(aBmpEx), aBeginUndo, "" ))
823  {
824  return true;
825  }
826  }
827  }
828 
829  return false;
830 }
831 
832 static bool lcl_SelHasAttrib( const ScDocument& rDoc, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
833  const ScMarkData& rTabSelection, HasAttrFlags nMask )
834 {
835  return std::any_of(rTabSelection.begin(), rTabSelection.end(),
836  [&](const SCTAB& rTab) { return rDoc.HasAttrib( nCol1, nRow1, rTab, nCol2, nRow2, rTab, nMask ); });
837 }
838 
839 // paste into sheet:
840 
841 // internal paste
842 
843 namespace {
844 
845 bool checkDestRangeForOverwrite(const ScRangeList& rDestRanges, const ScDocument& rDoc, const ScMarkData& rMark, weld::Window* pParentWnd)
846 {
847  bool bIsEmpty = true;
848  size_t nRangeSize = rDestRanges.size();
849  for (const auto& rTab : rMark)
850  {
851  for (size_t i = 0; i < nRangeSize && bIsEmpty; ++i)
852  {
853  const ScRange& rRange = rDestRanges[i];
854  bIsEmpty = rDoc.IsBlockEmpty(
855  rTab, rRange.aStart.Col(), rRange.aStart.Row(),
856  rRange.aEnd.Col(), rRange.aEnd.Row());
857  }
858  if (!bIsEmpty)
859  break;
860  }
861 
862  if (!bIsEmpty)
863  {
864  ScReplaceWarnBox aBox(pParentWnd);
865  if (aBox.run() != RET_YES)
866  {
867  // changing the configuration is within the ScReplaceWarnBox
868  return false;
869  }
870  }
871  return true;
872 }
873 
874 }
875 
877  ScPasteFunc nFunction, bool bSkipEmpty,
878  bool bTranspose, bool bAsLink,
879  InsCellCmd eMoveMode, InsertDeleteFlags nUndoExtraFlags,
880  bool bAllowDialogs )
881 {
882  if (!pClipDoc)
883  {
884  OSL_FAIL("PasteFromClip: pClipDoc=0 not allowed");
885  return false;
886  }
887 
888  if (GetViewData().SelectionForbidsCellFill())
889  return false;
890 
891  // undo: save all or no content
893  if (nFlags & InsertDeleteFlags::CONTENTS)
894  nContFlags |= InsertDeleteFlags::CONTENTS;
895  if (nFlags & InsertDeleteFlags::ATTRIB)
896  nContFlags |= InsertDeleteFlags::ATTRIB;
897  // move attributes to undo without copying them from clip to doc
898  InsertDeleteFlags nUndoFlags = nContFlags;
899  if (nUndoExtraFlags & InsertDeleteFlags::ATTRIB)
900  nUndoFlags |= InsertDeleteFlags::ATTRIB;
901  // do not copy note captions into undo document
902  nUndoFlags |= InsertDeleteFlags::NOCAPTIONS;
903 
904  ScClipParam& rClipParam = pClipDoc->GetClipParam();
905  if (rClipParam.isMultiRange())
906  {
907  // Source data is multi-range.
908  return PasteMultiRangesFromClip(
909  nFlags, pClipDoc, nFunction, bSkipEmpty, bTranspose, bAsLink, bAllowDialogs,
910  eMoveMode, nUndoFlags);
911  }
912 
913  ScMarkData& rMark = GetViewData().GetMarkData();
914  if (rMark.IsMultiMarked())
915  {
916  // Source data is single-range but destination is multi-range.
917  return PasteFromClipToMultiRanges(
918  nFlags, pClipDoc, nFunction, bSkipEmpty, bTranspose, bAsLink, bAllowDialogs,
919  eMoveMode, nUndoFlags);
920  }
921 
922  bool bCutMode = pClipDoc->IsCutMode(); // if transposing, take from original clipdoc
923  bool bIncludeFiltered = bCutMode;
924 
925  // paste drawing: also if InsertDeleteFlags::NOTE is set (to create drawing layer for note captions)
926  bool bPasteDraw = ( pClipDoc->GetDrawLayer() && ( nFlags & (InsertDeleteFlags::OBJECTS|InsertDeleteFlags::NOTE) ) );
927 
928  ScDocShellRef aTransShellRef; // for objects in xTransClip - must remain valid as long as xTransClip
929  ScDocument* pOrigClipDoc = nullptr;
930  ScDocumentUniquePtr xTransClip;
931  if ( bTranspose )
932  {
933  SCCOL nX;
934  SCROW nY;
935  // include filtered rows until TransposeClip can skip them
936  bIncludeFiltered = true;
937  pClipDoc->GetClipArea( nX, nY, true );
938  if ( nY > static_cast<sal_Int32>(pClipDoc->MaxCol()) ) // too many lines for transpose
939  {
940  ErrorMessage(STR_PASTE_FULL);
941  return false;
942  }
943  pOrigClipDoc = pClipDoc; // refs
944 
945  if ( bPasteDraw )
946  {
947  aTransShellRef = new ScDocShell; // DocShell needs a Ref immediately
948  aTransShellRef->DoInitNew();
949  }
950  ScDrawLayer::SetGlobalDrawPersist( aTransShellRef.get() );
951 
952  xTransClip.reset( new ScDocument( SCDOCMODE_CLIP ));
953  pClipDoc->TransposeClip( xTransClip.get(), nFlags, bAsLink );
954  pClipDoc = xTransClip.get();
955 
957  }
958 
959  // TODO: position this call better for performance.
960  ResetAutoSpellForContentChange();
961 
962  SCCOL nStartCol;
963  SCROW nStartRow;
964  SCTAB nStartTab;
965  SCCOL nEndCol;
966  SCROW nEndRow;
967  SCTAB nEndTab;
968  SCCOL nClipSizeX;
969  SCROW nClipSizeY;
970  pClipDoc->GetClipArea( nClipSizeX, nClipSizeY, true ); // size in clipboard doc
971 
972  // size in target doc: include filtered rows only if CutMode is set
973  SCCOL nDestSizeX;
974  SCROW nDestSizeY;
975  pClipDoc->GetClipArea( nDestSizeX, nDestSizeY, bIncludeFiltered );
976 
977  ScDocument& rDoc = GetViewData().GetDocument();
978  ScDocShell* pDocSh = GetViewData().GetDocShell();
979  SfxUndoManager* pUndoMgr = pDocSh->GetUndoManager();
980  const bool bRecord(rDoc.IsUndoEnabled());
981 
982  ScDocShellModificator aModificator( *pDocSh );
983 
984  ScRange aMarkRange;
985  ScMarkData aFilteredMark( rMark); // local copy for all modifications
986  ScMarkType eMarkType = GetViewData().GetSimpleArea( aMarkRange, aFilteredMark);
987  bool bMarkIsFiltered = (eMarkType == SC_MARK_SIMPLE_FILTERED);
988  bool bNoPaste = ((eMarkType != SC_MARK_SIMPLE && !bMarkIsFiltered) ||
989  (bMarkIsFiltered && (eMoveMode != INS_NONE || bAsLink)));
990 
991  if (!bNoPaste)
992  {
993  if (!rMark.IsMarked())
994  {
995  // Create a selection with clipboard row count and check that for
996  // filtered.
997  nStartCol = GetViewData().GetCurX();
998  nStartRow = GetViewData().GetCurY();
999  nStartTab = GetViewData().GetTabNo();
1000  nEndCol = nStartCol + nDestSizeX;
1001  nEndRow = nStartRow + nDestSizeY;
1002  nEndTab = nStartTab;
1003  aMarkRange = ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
1004  if (ScViewUtil::HasFiltered(aMarkRange, rDoc))
1005  {
1006  bMarkIsFiltered = true;
1007  // Fit to clipboard's row count unfiltered rows. If there is no
1008  // fit assume that pasting is not possible. Note that nDestSizeY is
1009  // size-1 (difference).
1010  if (!ScViewUtil::FitToUnfilteredRows(aMarkRange, rDoc, nDestSizeY+1))
1011  bNoPaste = true;
1012  }
1013  aFilteredMark.SetMarkArea( aMarkRange);
1014  }
1015  else
1016  {
1017  // Expand the marked area when the destination area is larger than the
1018  // current selection, to get the undo do the right thing. (i#106711)
1019  ScRange aRange;
1020  aFilteredMark.GetMarkArea( aRange );
1021  if( (aRange.aEnd.Col() - aRange.aStart.Col()) < nDestSizeX )
1022  {
1023  aRange.aEnd.SetCol(aRange.aStart.Col() + nDestSizeX);
1024  aFilteredMark.SetMarkArea(aRange);
1025  }
1026  }
1027  }
1028 
1029  if (bNoPaste)
1030  {
1031  ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
1032  return false;
1033  }
1034 
1035  SCROW nUnfilteredRows = aMarkRange.aEnd.Row() - aMarkRange.aStart.Row() + 1;
1036  ScRangeList aRangeList;
1037  if (bMarkIsFiltered)
1038  {
1039  ScViewUtil::UnmarkFiltered(aFilteredMark, rDoc);
1040  aFilteredMark.FillRangeListWithMarks( &aRangeList, false);
1041  nUnfilteredRows = 0;
1042  size_t ListSize = aRangeList.size();
1043  for ( size_t i = 0; i < ListSize; ++i )
1044  {
1045  ScRange & r = aRangeList[i];
1046  nUnfilteredRows += r.aEnd.Row() - r.aStart.Row() + 1;
1047  }
1048 #if 0
1049  /* This isn't needed but could be a desired restriction. */
1050  // For filtered, destination rows have to be an exact multiple of
1051  // source rows. Note that nDestSizeY is size-1 (difference), so
1052  // nDestSizeY==0 fits always.
1053  if ((nUnfilteredRows % (nDestSizeY+1)) != 0)
1054  {
1055  /* FIXME: this should be a more descriptive error message then. */
1056  ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
1057  return false;
1058  }
1059 #endif
1060  }
1061 
1062  // Also for a filtered selection the area is used, for undo et al.
1063  if ( aFilteredMark.IsMarked() || bMarkIsFiltered )
1064  {
1065  aMarkRange.GetVars( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
1066  SCCOL nBlockAddX = nEndCol-nStartCol;
1067  SCROW nBlockAddY = nEndRow-nStartRow;
1068 
1069  // request, if the selection is greater than one row/column, but smaller
1070  // as the Clipboard (then inserting is done beyond the selection)
1071 
1072  // ClipSize is not size, but difference
1073  if ( ( nBlockAddX != 0 && nBlockAddX < nDestSizeX ) ||
1074  ( nBlockAddY != 0 && nBlockAddY < nDestSizeY ) ||
1075  ( bMarkIsFiltered && nUnfilteredRows < nDestSizeY+1 ) )
1076  {
1077  ScWaitCursorOff aWaitOff( GetFrameWin() );
1078  OUString aMessage = ScResId( STR_PASTE_BIGGER );
1079 
1080  std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetViewData().GetDialogParent(),
1081  VclMessageType::Question, VclButtonsType::YesNo,
1082  aMessage));
1083  xQueryBox->set_default_response(RET_NO);
1084  if (xQueryBox->run() != RET_YES)
1085  {
1086  return false;
1087  }
1088  }
1089 
1090  if (nBlockAddX <= nDestSizeX)
1091  nEndCol = nStartCol + nDestSizeX;
1092 
1093  if (nBlockAddY <= nDestSizeY)
1094  {
1095  nEndRow = nStartRow + nDestSizeY;
1096  if (bMarkIsFiltered || nEndRow > aMarkRange.aEnd.Row())
1097  {
1098  // Same as above if nothing was marked: re-fit selection to
1099  // unfiltered rows. Extending the selection actually may
1100  // introduce filtered rows where there weren't any before, so
1101  // we also need to test for that.
1102  aMarkRange = ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
1103  if (bMarkIsFiltered || ScViewUtil::HasFiltered(aMarkRange, rDoc))
1104  {
1105  bMarkIsFiltered = true;
1106  // Worst case: all rows up to the end of the sheet are filtered.
1107  if (!ScViewUtil::FitToUnfilteredRows(aMarkRange, rDoc, nDestSizeY+1))
1108  {
1109  ErrorMessage(STR_PASTE_FULL);
1110  return false;
1111  }
1112  }
1113  aMarkRange.GetVars( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
1114  aFilteredMark.SetMarkArea( aMarkRange);
1115  if (bMarkIsFiltered)
1116  {
1117  ScViewUtil::UnmarkFiltered(aFilteredMark, rDoc);
1118  aFilteredMark.FillRangeListWithMarks( &aRangeList, true);
1119  }
1120  }
1121  }
1122  }
1123  else
1124  {
1125  nStartCol = GetViewData().GetCurX();
1126  nStartRow = GetViewData().GetCurY();
1127  nStartTab = GetViewData().GetTabNo();
1128  nEndCol = nStartCol + nDestSizeX;
1129  nEndRow = nStartRow + nDestSizeY;
1130  nEndTab = nStartTab;
1131  }
1132 
1133  bool bOffLimits = !rDoc.ValidCol(nEndCol) || !rDoc.ValidRow(nEndRow);
1134 
1135  // target-range, as displayed:
1136  ScRange aUserRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab );
1137 
1138  // should lines be inserted?
1139  // ( too large nEndCol/nEndRow are detected below)
1140  bool bInsertCells = ( eMoveMode != INS_NONE && !bOffLimits );
1141  if ( bInsertCells )
1142  {
1143  // Instead of EnterListAction, the paste undo action is merged into the
1144  // insert action, so Repeat can insert the right cells
1145 
1146  MarkRange( aUserRange ); // set through CopyFromClip
1147 
1148  // CutMode is reset on insertion of cols/rows but needed again on cell move
1149  bool bCut = pClipDoc->IsCutMode();
1150  if (!InsertCells( eMoveMode, bRecord, true )) // is inserting possible?
1151  {
1152  return false;
1153  // #i21036# EnterListAction isn't used, and InsertCells doesn't insert
1154  // its undo action on failure, so no undo handling is needed here
1155  }
1156  if ( bCut )
1157  pClipDoc->SetCutMode( bCut );
1158  }
1159  else if (!bOffLimits)
1160  {
1161  bool bAskIfNotEmpty = bAllowDialogs &&
1162  ( nFlags & InsertDeleteFlags::CONTENTS ) &&
1163  nFunction == ScPasteFunc::NONE &&
1164  SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1165  if ( bAskIfNotEmpty )
1166  {
1167  ScRangeList aTestRanges(aUserRange);
1168  if (!checkDestRangeForOverwrite(aTestRanges, rDoc, aFilteredMark, GetViewData().GetDialogParent()))
1169  return false;
1170  }
1171  }
1172 
1173  SCCOL nClipStartX; // enlarge clipboard-range
1174  SCROW nClipStartY;
1175  pClipDoc->GetClipStart( nClipStartX, nClipStartY );
1176  SCCOL nUndoEndCol = nClipStartX + nClipSizeX;
1177  SCROW nUndoEndRow = nClipStartY + nClipSizeY; // end of source area in clipboard document
1178  bool bClipOver = false;
1179  // #i68690# ExtendMerge for the clip doc must be called with the clipboard's sheet numbers.
1180  // The same end column/row can be used for all calls because the clip doc doesn't contain
1181  // content outside the clip area.
1182  for (SCTAB nClipTab=0; nClipTab < pClipDoc->GetTableCount(); nClipTab++)
1183  if ( pClipDoc->HasTable(nClipTab) )
1184  if ( pClipDoc->ExtendMerge( nClipStartX,nClipStartY, nUndoEndCol,nUndoEndRow, nClipTab ) )
1185  bClipOver = true;
1186  nUndoEndCol -= nClipStartX + nClipSizeX;
1187  nUndoEndRow -= nClipStartY + nClipSizeY; // now contains only the difference added by ExtendMerge
1188  nUndoEndCol = sal::static_int_cast<SCCOL>( nUndoEndCol + nEndCol );
1189  nUndoEndRow = sal::static_int_cast<SCROW>( nUndoEndRow + nEndRow ); // destination area, expanded for merged cells
1190 
1191  if (nUndoEndCol>pClipDoc->MaxCol() || nUndoEndRow>pClipDoc->MaxRow())
1192  {
1193  ErrorMessage(STR_PASTE_FULL);
1194  return false;
1195  }
1196 
1197  rDoc.ExtendMergeSel( nStartCol,nStartRow, nUndoEndCol,nUndoEndRow, aFilteredMark );
1198 
1199  // check cell-protection
1200 
1201  ScEditableTester aTester( rDoc, nStartTab, nStartCol,nStartRow, nUndoEndCol,nUndoEndRow );
1202  if (!aTester.IsEditable())
1203  {
1204  ErrorMessage(aTester.GetMessageId());
1205  return false;
1206  }
1207 
1210 
1211  ScDocFunc& rDocFunc = pDocSh->GetDocFunc();
1212  if ( bRecord )
1213  {
1214  OUString aUndo = ScResId( pClipDoc->IsCutMode() ? STR_UNDO_MOVE : STR_UNDO_COPY );
1215  pUndoMgr->EnterListAction( aUndo, aUndo, 0, GetViewData().GetViewShell()->GetViewShellId() );
1216  }
1217 
1218  if (bClipOver)
1219  if (lcl_SelHasAttrib( rDoc, nStartCol,nStartRow, nUndoEndCol,nUndoEndRow, aFilteredMark, HasAttrFlags::Overlapped ))
1220  { // "Cell merge not possible if cells already merged"
1221  ScDocAttrIterator aIter( rDoc, nStartTab, nStartCol, nStartRow, nUndoEndCol, nUndoEndRow );
1222  const ScPatternAttr* pPattern = nullptr;
1223  SCCOL nCol = -1;
1224  SCROW nRow1 = -1;
1225  SCROW nRow2 = -1;
1226  while ( ( pPattern = aIter.GetNext( nCol, nRow1, nRow2 ) ) != nullptr )
1227  {
1228  const ScMergeAttr& rMergeFlag = pPattern->GetItem(ATTR_MERGE);
1229  const ScMergeFlagAttr& rMergeFlagAttr = pPattern->GetItem(ATTR_MERGE_FLAG);
1230  if (rMergeFlag.IsMerged() || rMergeFlagAttr.IsOverlapped())
1231  {
1232  ScRange aRange(nCol, nRow1, nStartTab);
1233  rDoc.ExtendOverlapped(aRange);
1234  rDoc.ExtendMerge(aRange, true);
1235  rDocFunc.UnmergeCells(aRange, bRecord, nullptr /*TODO: should pass combined UndoDoc if bRecord*/);
1236  }
1237  }
1238  }
1239 
1240  if ( !bCutMode )
1241  {
1242  ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
1243  if ( pChangeTrack )
1244  pChangeTrack->ResetLastCut(); // no more cut-mode
1245  }
1246 
1247  bool bColInfo = ( nStartRow==0 && nEndRow==rDoc.MaxRow() );
1248  bool bRowInfo = ( nStartCol==0 && nEndCol==rDoc.MaxCol() );
1249 
1250  ScDocumentUniquePtr pUndoDoc;
1251  std::unique_ptr<ScDocument> pRefUndoDoc;
1252  std::unique_ptr<ScRefUndoData> pUndoData;
1253 
1254  if ( bRecord )
1255  {
1256  pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1257  pUndoDoc->InitUndoSelected( rDoc, aFilteredMark, bColInfo, bRowInfo );
1258 
1259  // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
1260  SCTAB nTabCount = rDoc.GetTableCount();
1261  rDoc.CopyToDocument( nStartCol, nStartRow, 0, nUndoEndCol, nUndoEndRow, nTabCount-1,
1262  nUndoFlags, false, *pUndoDoc );
1263 
1264  if ( bCutMode )
1265  {
1266  pRefUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1267  pRefUndoDoc->InitUndo( rDoc, 0, nTabCount-1 );
1268 
1269  pUndoData.reset(new ScRefUndoData( &rDoc ));
1270  }
1271  }
1272 
1273  sal_uInt16 nExtFlags = 0;
1274  pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab,
1275  nEndCol, nEndRow, nEndTab ); // content before the change
1276 
1277  if (GetViewData().IsActive())
1278  {
1279  DoneBlockMode();
1280  InitOwnBlockMode();
1281  }
1282  rMark.SetMarkArea( aUserRange );
1283  MarkDataChanged();
1284 
1285  // copy from clipboard
1286  // save original data in case of calculation
1287 
1288  ScDocumentUniquePtr pMixDoc;
1289  if (nFunction != ScPasteFunc::NONE)
1290  {
1291  bSkipEmpty = false;
1292  if ( nFlags & InsertDeleteFlags::CONTENTS )
1293  {
1294  pMixDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1295  pMixDoc->InitUndo( rDoc, nStartTab, nEndTab );
1296  rDoc.CopyToDocument(nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
1297  InsertDeleteFlags::CONTENTS, false, *pMixDoc);
1298  }
1299  }
1300 
1301  /* Make draw layer and start drawing undo.
1302  - Needed before AdjustBlockHeight to track moved drawing objects.
1303  - Needed before rDoc.CopyFromClip to track inserted note caption objects.
1304  */
1305  if ( bPasteDraw )
1306  pDocSh->MakeDrawLayer();
1307  if ( bRecord )
1308  rDoc.BeginDrawUndo();
1309 
1310  InsertDeleteFlags nNoObjFlags = nFlags & ~InsertDeleteFlags::OBJECTS;
1311  if (!bAsLink)
1312  {
1313  // copy normally (original range)
1314  rDoc.CopyFromClip( aUserRange, aFilteredMark, nNoObjFlags,
1315  pRefUndoDoc.get(), pClipDoc, true, false, bIncludeFiltered,
1316  bSkipEmpty, (bMarkIsFiltered ? &aRangeList : nullptr) );
1317 
1318  // adapt refs manually in case of transpose
1319  if ( bTranspose && bCutMode && (nFlags & InsertDeleteFlags::CONTENTS) )
1320  rDoc.UpdateTranspose( aUserRange.aStart, pOrigClipDoc, aFilteredMark, pRefUndoDoc.get() );
1321  }
1322  else if (!bTranspose)
1323  {
1324  // copy with bAsLink=TRUE
1325  rDoc.CopyFromClip( aUserRange, aFilteredMark, nNoObjFlags, pRefUndoDoc.get(), pClipDoc,
1326  true, true, bIncludeFiltered, bSkipEmpty );
1327  }
1328  else
1329  {
1330  // copy all content (TransClipDoc contains only formula)
1331  rDoc.CopyFromClip( aUserRange, aFilteredMark, nContFlags, pRefUndoDoc.get(), pClipDoc );
1332  }
1333 
1334  // skipped rows and merged cells don't mix
1335  if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
1336  rDocFunc.UnmergeCells( aUserRange, false, nullptr );
1337 
1338  rDoc.ExtendMergeSel( nStartCol, nStartRow, nEndCol, nEndRow, aFilteredMark, true ); // refresh
1339  // new range
1340 
1341  if ( pMixDoc ) // calculate with original data?
1342  {
1343  rDoc.MixDocument( aUserRange, nFunction, bSkipEmpty, *pMixDoc );
1344  }
1345  pMixDoc.reset();
1346 
1347  AdjustBlockHeight(); // update row heights before pasting objects
1348 
1349  ::std::vector< OUString > aExcludedChartNames;
1350  SdrPage* pPage = nullptr;
1351 
1352  if ( nFlags & InsertDeleteFlags::OBJECTS )
1353  {
1354  ScDrawView* pScDrawView = GetScDrawView();
1355  SdrModel* pModel = ( pScDrawView ? pScDrawView->GetModel() : nullptr );
1356  pPage = ( pModel ? pModel->GetPage( static_cast< sal_uInt16 >( nStartTab ) ) : nullptr );
1357  if ( pPage )
1358  {
1359  ScChartHelper::GetChartNames( aExcludedChartNames, pPage );
1360  }
1361 
1362  // Paste the drawing objects after the row heights have been updated.
1363 
1364  rDoc.CopyFromClip( aUserRange, aFilteredMark, InsertDeleteFlags::OBJECTS, pRefUndoDoc.get(), pClipDoc,
1365  true, false, bIncludeFiltered );
1366  }
1367 
1368  pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab,
1369  nEndCol, nEndRow, nEndTab ); // content after the change
1370 
1371  // if necessary, delete autofilter-heads
1372  if (bCutMode)
1373  if (rDoc.RefreshAutoFilter( nClipStartX,nClipStartY, nClipStartX+nClipSizeX,
1374  nClipStartY+nClipSizeY, nStartTab ))
1375  {
1376  pDocSh->PostPaint(
1377  ScRange(nClipStartX, nClipStartY, nStartTab, nClipStartX+nClipSizeX, nClipStartY, nStartTab),
1379  }
1380 
1382 
1383  if ( bRecord )
1384  {
1385  ScDocumentUniquePtr pRedoDoc;
1386  // copy redo data after appearance of the first undo
1387  // don't create Redo-Doc without RefUndoDoc
1388 
1389  if (pRefUndoDoc)
1390  {
1391  pRedoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1392  pRedoDoc->InitUndo( rDoc, nStartTab, nEndTab, bColInfo, bRowInfo );
1393 
1394  // move adapted refs to Redo-Doc
1395 
1396  SCTAB nTabCount = rDoc.GetTableCount();
1397  pRedoDoc->AddUndoTab( 0, nTabCount-1 );
1398  rDoc.CopyUpdated( pRefUndoDoc.get(), pRedoDoc.get() );
1399 
1400  // move old refs to Undo-Doc
1401 
1402  // not charts?
1403  pUndoDoc->AddUndoTab( 0, nTabCount-1 );
1404  pRefUndoDoc->DeleteArea( nStartCol, nStartRow, nEndCol, nEndRow, aFilteredMark, InsertDeleteFlags::ALL );
1405  pRefUndoDoc->CopyToDocument( 0,0,0, pUndoDoc->MaxCol(), pUndoDoc->MaxRow(), nTabCount-1,
1406  InsertDeleteFlags::FORMULA, false, *pUndoDoc );
1407  pRefUndoDoc.reset();
1408  }
1409 
1410  // DeleteUnchanged for pUndoData is in ScUndoPaste ctor,
1411  // UndoData for redo is made during first undo
1412 
1413  ScUndoPasteOptions aOptions; // store options for repeat
1414  aOptions.nFunction = nFunction;
1415  aOptions.bSkipEmpty = bSkipEmpty;
1416  aOptions.bTranspose = bTranspose;
1417  aOptions.bAsLink = bAsLink;
1418  aOptions.eMoveMode = eMoveMode;
1419 
1420  std::unique_ptr<SfxUndoAction> pUndo(new ScUndoPaste(
1421  pDocSh, ScRange(nStartCol, nStartRow, nStartTab, nUndoEndCol, nUndoEndRow, nEndTab),
1422  aFilteredMark, std::move(pUndoDoc), std::move(pRedoDoc), nFlags | nUndoFlags, std::move(pUndoData),
1423  false, &aOptions )); // false = Redo data not yet copied
1424 
1425  if ( bInsertCells )
1426  {
1427  // Merge the paste undo action into the insert action.
1428  // Use ScUndoWrapper so the ScUndoPaste pointer can be stored in the insert action.
1429 
1430  pUndoMgr->AddUndoAction( std::make_unique<ScUndoWrapper>( std::move(pUndo) ), true );
1431  }
1432  else
1433  pUndoMgr->AddUndoAction( std::move(pUndo) );
1434  pUndoMgr->LeaveListAction();
1435  }
1436 
1438  if (bColInfo)
1439  {
1440  nPaint |= PaintPartFlags::Top;
1441  nUndoEndCol = rDoc.MaxCol(); // just for drawing !
1442  }
1443  if (bRowInfo)
1444  {
1445  nPaint |= PaintPartFlags::Left;
1446  nUndoEndRow = rDoc.MaxRow(); // just for drawing !
1447  }
1448  pDocSh->PostPaint(
1449  ScRange(nStartCol, nStartRow, nStartTab, nUndoEndCol, nUndoEndRow, nEndTab),
1450  nPaint, nExtFlags);
1451  // AdjustBlockHeight has already been called above
1452 
1453  aModificator.SetDocumentModified();
1454  PostPasteFromClip(aUserRange, rMark);
1455 
1456  if ( nFlags & InsertDeleteFlags::OBJECTS )
1457  {
1458  ScModelObj* pModelObj = comphelper::getUnoTunnelImplementation<ScModelObj>( pDocSh->GetModel() );
1459  if ( pPage && pModelObj )
1460  {
1461  bool bSameDoc = ( rClipParam.getSourceDocID() == rDoc.GetDocumentID() );
1462  const ScRangeListVector& rProtectedChartRangesVector( rClipParam.maProtectedChartRangesVector );
1463  ScChartHelper::CreateProtectedChartListenersAndNotify( rDoc, pPage, pModelObj, nStartTab,
1464  rProtectedChartRangesVector, aExcludedChartNames, bSameDoc );
1465  }
1466  }
1467  OUString aStartAddress = aMarkRange.aStart.GetColRowString();
1468  OUString aEndAddress = aMarkRange.aEnd.GetColRowString();
1469  collectUIInformation({{"RANGE", aStartAddress + ":" + aEndAddress}}, "PASTE");
1470  return true;
1471 }
1472 
1474  InsertDeleteFlags nFlags, ScDocument* pClipDoc, ScPasteFunc nFunction,
1475  bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs,
1476  InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags)
1477 {
1478  ScViewData& rViewData = GetViewData();
1479  ScDocument& rDoc = rViewData.GetDocument();
1480  ScDocShell* pDocSh = rViewData.GetDocShell();
1481  ScMarkData aMark(rViewData.GetMarkData());
1482  const ScAddress& rCurPos = rViewData.GetCurPos();
1483  ScClipParam& rClipParam = pClipDoc->GetClipParam();
1484  SCCOL nColSize = rClipParam.getPasteColSize();
1485  SCROW nRowSize = rClipParam.getPasteRowSize();
1486 
1487  if (bTranspose)
1488  {
1489  if (static_cast<SCROW>(rCurPos.Col()) + nRowSize-1 > static_cast<SCROW>(pClipDoc->MaxCol()))
1490  {
1491  ErrorMessage(STR_PASTE_FULL);
1492  return false;
1493  }
1494 
1496  pClipDoc->TransposeClip(pTransClip.get(), nFlags, bAsLink);
1497  pClipDoc = pTransClip.release();
1498  SCCOL nTempColSize = nColSize;
1499  nColSize = static_cast<SCCOL>(nRowSize);
1500  nRowSize = static_cast<SCROW>(nTempColSize);
1501  }
1502 
1503  if (!rDoc.ValidCol(rCurPos.Col()+nColSize-1) || !rDoc.ValidRow(rCurPos.Row()+nRowSize-1))
1504  {
1505  ErrorMessage(STR_PASTE_FULL);
1506  return false;
1507  }
1508 
1509  // Determine the first and last selected sheet numbers.
1510  SCTAB nTab1 = aMark.GetFirstSelected();
1511  SCTAB nTab2 = aMark.GetLastSelected();
1512 
1513  ScDocShellModificator aModificator(*pDocSh);
1514 
1515  // For multi-selection paste, we don't support cell duplication for larger
1516  // destination range. In case the destination is marked, we reset it to
1517  // the clip size.
1518  ScRange aMarkedRange(rCurPos.Col(), rCurPos.Row(), nTab1,
1519  rCurPos.Col()+nColSize-1, rCurPos.Row()+nRowSize-1, nTab2);
1520 
1521  // Extend the marked range to account for filtered rows in the destination
1522  // area.
1523  if (ScViewUtil::HasFiltered(aMarkedRange, rDoc))
1524  {
1525  if (!ScViewUtil::FitToUnfilteredRows(aMarkedRange, rDoc, nRowSize))
1526  return false;
1527  }
1528 
1529  bool bAskIfNotEmpty =
1530  bAllowDialogs && (nFlags & InsertDeleteFlags::CONTENTS) &&
1531  nFunction == ScPasteFunc::NONE && SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1532 
1533  if (bAskIfNotEmpty)
1534  {
1535  ScRangeList aTestRanges(aMarkedRange);
1536  if (!checkDestRangeForOverwrite(aTestRanges, rDoc, aMark, GetViewData().GetDialogParent()))
1537  return false;
1538  }
1539 
1540  aMark.SetMarkArea(aMarkedRange);
1541  MarkRange(aMarkedRange);
1542 
1543  bool bInsertCells = (eMoveMode != INS_NONE);
1544  if (bInsertCells)
1545  {
1546  if (!InsertCells(eMoveMode, rDoc.IsUndoEnabled(), true))
1547  return false;
1548  }
1549 
1550  // TODO: position this call better for performance.
1551  ResetAutoSpellForContentChange();
1552 
1553  bool bRowInfo = ( aMarkedRange.aStart.Col()==0 && aMarkedRange.aEnd.Col()==pClipDoc->MaxCol() );
1554  ScDocumentUniquePtr pUndoDoc;
1555  if (rDoc.IsUndoEnabled())
1556  {
1557  pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1558  pUndoDoc->InitUndoSelected(rDoc, aMark, false, bRowInfo);
1559  rDoc.CopyToDocument(aMarkedRange, nUndoFlags, false, *pUndoDoc, &aMark);
1560  }
1561 
1562  ScDocumentUniquePtr pMixDoc;
1563  if ( bSkipEmpty || nFunction != ScPasteFunc::NONE)
1564  {
1565  if ( nFlags & InsertDeleteFlags::CONTENTS )
1566  {
1567  pMixDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1568  pMixDoc->InitUndoSelected(rDoc, aMark);
1569  rDoc.CopyToDocument(aMarkedRange, InsertDeleteFlags::CONTENTS, false, *pMixDoc, &aMark);
1570  }
1571  }
1572 
1573  /* Make draw layer and start drawing undo.
1574  - Needed before AdjustBlockHeight to track moved drawing objects.
1575  - Needed before rDoc.CopyFromClip to track inserted note caption objects.
1576  */
1577  if (nFlags & InsertDeleteFlags::OBJECTS)
1578  pDocSh->MakeDrawLayer();
1579  if (rDoc.IsUndoEnabled())
1580  rDoc.BeginDrawUndo();
1581 
1582  InsertDeleteFlags nNoObjFlags = nFlags & ~InsertDeleteFlags::OBJECTS;
1583  rDoc.CopyMultiRangeFromClip(rCurPos, aMark, nNoObjFlags, pClipDoc,
1584  true, bAsLink, false, bSkipEmpty);
1585 
1586  if (pMixDoc)
1587  rDoc.MixDocument(aMarkedRange, nFunction, bSkipEmpty, *pMixDoc);
1588 
1589  AdjustBlockHeight(); // update row heights before pasting objects
1590 
1591  if (nFlags & InsertDeleteFlags::OBJECTS)
1592  {
1593  // Paste the drawing objects after the row heights have been updated.
1594  rDoc.CopyMultiRangeFromClip(rCurPos, aMark, InsertDeleteFlags::OBJECTS, pClipDoc,
1595  true, false, false, true);
1596  }
1597 
1598  if (bRowInfo)
1599  pDocSh->PostPaint(aMarkedRange.aStart.Col(), aMarkedRange.aStart.Row(), nTab1, pClipDoc->MaxCol(), pClipDoc->MaxRow(), nTab1, PaintPartFlags::Grid|PaintPartFlags::Left);
1600  else
1601  {
1602  ScRange aTmp = aMarkedRange;
1603  aTmp.aStart.SetTab(nTab1);
1604  aTmp.aEnd.SetTab(nTab1);
1605  pDocSh->PostPaint(aTmp, PaintPartFlags::Grid);
1606  }
1607 
1608  if (rDoc.IsUndoEnabled())
1609  {
1610  SfxUndoManager* pUndoMgr = pDocSh->GetUndoManager();
1611  OUString aUndo = ScResId(
1612  pClipDoc->IsCutMode() ? STR_UNDO_CUT : STR_UNDO_COPY);
1613  pUndoMgr->EnterListAction(aUndo, aUndo, 0, GetViewData().GetViewShell()->GetViewShellId());
1614 
1615  ScUndoPasteOptions aOptions; // store options for repeat
1616  aOptions.nFunction = nFunction;
1617  aOptions.bSkipEmpty = bSkipEmpty;
1618  aOptions.bTranspose = bTranspose;
1619  aOptions.bAsLink = bAsLink;
1620  aOptions.eMoveMode = eMoveMode;
1621 
1622  std::unique_ptr<ScUndoPaste> pUndo(new ScUndoPaste(pDocSh,
1623  aMarkedRange, aMark, std::move(pUndoDoc), nullptr, nFlags|nUndoFlags, nullptr, false, &aOptions));
1624 
1625  if (bInsertCells)
1626  pUndoMgr->AddUndoAction(std::make_unique<ScUndoWrapper>(std::move(pUndo)), true);
1627  else
1628  pUndoMgr->AddUndoAction(std::move(pUndo));
1629 
1630  pUndoMgr->LeaveListAction();
1631  }
1632 
1633  aModificator.SetDocumentModified();
1634  PostPasteFromClip(aMarkedRange, aMark);
1635  return true;
1636 }
1637 
1639  InsertDeleteFlags nFlags, ScDocument* pClipDoc, ScPasteFunc nFunction,
1640  bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs,
1641  InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags )
1642 {
1643  if (bTranspose)
1644  {
1645  // We don't allow transpose for this yet.
1646  ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
1647  return false;
1648  }
1649 
1650  if (eMoveMode != INS_NONE)
1651  {
1652  // We don't allow insertion mode either. Too complicated.
1653  ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
1654  return false;
1655  }
1656 
1657  ScViewData& rViewData = GetViewData();
1658  ScClipParam& rClipParam = pClipDoc->GetClipParam();
1659  if (rClipParam.mbCutMode)
1660  {
1661  // No cut and paste with this, please.
1662  ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
1663  return false;
1664  }
1665 
1666  const ScAddress& rCurPos = rViewData.GetCurPos();
1667  ScDocument& rDoc = rViewData.GetDocument();
1668 
1669  ScRange aSrcRange = rClipParam.getWholeRange();
1670  SCROW nRowSize = aSrcRange.aEnd.Row() - aSrcRange.aStart.Row() + 1;
1671  SCCOL nColSize = aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1;
1672 
1673  if (!rDoc.ValidCol(rCurPos.Col()+nColSize-1) || !rDoc.ValidRow(rCurPos.Row()+nRowSize-1))
1674  {
1675  ErrorMessage(STR_PASTE_FULL);
1676  return false;
1677  }
1678 
1679  ScMarkData aMark(rViewData.GetMarkData());
1680 
1681  ScRangeList aRanges;
1682  aMark.MarkToSimple();
1683  aMark.FillRangeListWithMarks(&aRanges, false);
1684  if (!ScClipUtil::CheckDestRanges(rDoc, nColSize, nRowSize, aMark, aRanges))
1685  {
1686  ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
1687  return false;
1688  }
1689 
1690  ScDocShell* pDocSh = rViewData.GetDocShell();
1691 
1692  ScDocShellModificator aModificator(*pDocSh);
1693 
1694  bool bAskIfNotEmpty =
1695  bAllowDialogs && (nFlags & InsertDeleteFlags::CONTENTS) &&
1696  nFunction == ScPasteFunc::NONE && SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1697 
1698  if (bAskIfNotEmpty)
1699  {
1700  if (!checkDestRangeForOverwrite(aRanges, rDoc, aMark, GetViewData().GetDialogParent()))
1701  return false;
1702  }
1703 
1704  // TODO: position this call better for performance.
1705  ResetAutoSpellForContentChange();
1706 
1707  ScDocumentUniquePtr pUndoDoc;
1708  if (rDoc.IsUndoEnabled())
1709  {
1710  pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1711  pUndoDoc->InitUndoSelected(rDoc, aMark);
1712  for (size_t i = 0, n = aRanges.size(); i < n; ++i)
1713  {
1714  rDoc.CopyToDocument(
1715  aRanges[i], nUndoFlags, false, *pUndoDoc, &aMark);
1716  }
1717  }
1718 
1719  ScDocumentUniquePtr pMixDoc;
1720  if (bSkipEmpty || nFunction != ScPasteFunc::NONE)
1721  {
1722  if (nFlags & InsertDeleteFlags::CONTENTS)
1723  {
1724  pMixDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1725  pMixDoc->InitUndoSelected(rDoc, aMark);
1726  for (size_t i = 0, n = aRanges.size(); i < n; ++i)
1727  {
1728  rDoc.CopyToDocument(
1729  aRanges[i], InsertDeleteFlags::CONTENTS, false, *pMixDoc, &aMark);
1730  }
1731  }
1732  }
1733 
1734  if (nFlags & InsertDeleteFlags::OBJECTS)
1735  pDocSh->MakeDrawLayer();
1736  if (rDoc.IsUndoEnabled())
1737  rDoc.BeginDrawUndo();
1738 
1739  // First, paste everything but the drawing objects.
1740  for (size_t i = 0, n = aRanges.size(); i < n; ++i)
1741  {
1742  rDoc.CopyFromClip(
1743  aRanges[i], aMark, (nFlags & ~InsertDeleteFlags::OBJECTS), nullptr, pClipDoc,
1744  false, false, true, bSkipEmpty);
1745  }
1746 
1747  if (pMixDoc)
1748  {
1749  for (size_t i = 0, n = aRanges.size(); i < n; ++i)
1750  rDoc.MixDocument(aRanges[i], nFunction, bSkipEmpty, *pMixDoc);
1751  }
1752 
1753  AdjustBlockHeight(); // update row heights before pasting objects
1754 
1755  // Then paste the objects.
1756  if (nFlags & InsertDeleteFlags::OBJECTS)
1757  {
1758  for (size_t i = 0, n = aRanges.size(); i < n; ++i)
1759  {
1760  rDoc.CopyFromClip(
1761  aRanges[i], aMark, InsertDeleteFlags::OBJECTS, nullptr, pClipDoc,
1762  false, false, true, bSkipEmpty);
1763  }
1764  }
1765 
1766  // Refresh the range that includes all pasted ranges. We only need to
1767  // refresh the current sheet.
1769  bool bRowInfo = (aSrcRange.aStart.Col()==0 && aSrcRange.aEnd.Col()==pClipDoc->MaxCol());
1770  if (bRowInfo)
1771  nPaint |= PaintPartFlags::Left;
1772  pDocSh->PostPaint(aRanges, nPaint);
1773 
1774  if (rDoc.IsUndoEnabled())
1775  {
1776  SfxUndoManager* pUndoMgr = pDocSh->GetUndoManager();
1777  OUString aUndo = ScResId(
1778  pClipDoc->IsCutMode() ? STR_UNDO_CUT : STR_UNDO_COPY);
1779  pUndoMgr->EnterListAction(aUndo, aUndo, 0, GetViewData().GetViewShell()->GetViewShellId());
1780 
1781  ScUndoPasteOptions aOptions; // store options for repeat
1782  aOptions.nFunction = nFunction;
1783  aOptions.bSkipEmpty = bSkipEmpty;
1784  aOptions.bTranspose = bTranspose;
1785  aOptions.bAsLink = bAsLink;
1786  aOptions.eMoveMode = eMoveMode;
1787 
1788 
1789  pUndoMgr->AddUndoAction(
1790  std::make_unique<ScUndoPaste>(
1791  pDocSh, aRanges, aMark, std::move(pUndoDoc), nullptr, nFlags|nUndoFlags, nullptr, false, &aOptions));
1792  pUndoMgr->LeaveListAction();
1793  }
1794 
1795  aModificator.SetDocumentModified();
1796  PostPasteFromClip(aRanges, aMark);
1797 
1798  return false;
1799 }
1800 
1801 void ScViewFunc::PostPasteFromClip(const ScRangeList& rPasteRanges, const ScMarkData& rMark)
1802 {
1803  ScViewData& rViewData = GetViewData();
1804  ScDocShell* pDocSh = rViewData.GetDocShell();
1805  pDocSh->UpdateOle(rViewData);
1806 
1807  SelectionChanged(true);
1808 
1810  if (!pModelObj)
1811  return;
1812 
1813  ScRangeList aChangeRanges;
1814  for (size_t i = 0, n = rPasteRanges.size(); i < n; ++i)
1815  {
1816  const ScRange& r = rPasteRanges[i];
1817  for (const auto& rTab : rMark)
1818  {
1819  ScRange aChangeRange(r);
1820  aChangeRange.aStart.SetTab(rTab);
1821  aChangeRange.aEnd.SetTab(rTab);
1822  aChangeRanges.push_back(aChangeRange);
1823  }
1824  }
1825  HelperNotifyChanges::Notify(*pModelObj, aChangeRanges);
1826 }
1827 
1828 // D R A G A N D D R O P
1829 
1830 // inside the doc
1831 
1832 bool ScViewFunc::MoveBlockTo( const ScRange& rSource, const ScAddress& rDestPos,
1833  bool bCut )
1834 {
1835  ScDocShell* pDocSh = GetViewData().GetDocShell();
1836  HideAllCursors();
1837 
1838  ResetAutoSpellForContentChange();
1839 
1840  bool bSuccess = true;
1841  SCTAB nDestTab = rDestPos.Tab();
1842  const ScMarkData& rMark = GetViewData().GetMarkData();
1843  if ( rSource.aStart.Tab() == nDestTab && rSource.aEnd.Tab() == nDestTab && rMark.GetSelectCount() > 1 )
1844  {
1845  // moving within one table and several tables selected -> apply to all selected tables
1846 
1847  OUString aUndo = ScResId( bCut ? STR_UNDO_MOVE : STR_UNDO_COPY );
1848  pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo, 0, GetViewData().GetViewShell()->GetViewShellId() );
1849 
1850  // collect ranges of consecutive selected tables
1851 
1852  ScRange aLocalSource = rSource;
1853  ScAddress aLocalDest = rDestPos;
1854  SCTAB nTabCount = pDocSh->GetDocument().GetTableCount();
1855  SCTAB nStartTab = 0;
1856  while ( nStartTab < nTabCount && bSuccess )
1857  {
1858  while ( nStartTab < nTabCount && !rMark.GetTableSelect(nStartTab) )
1859  ++nStartTab;
1860  if ( nStartTab < nTabCount )
1861  {
1862  SCTAB nEndTab = nStartTab;
1863  while ( nEndTab+1 < nTabCount && rMark.GetTableSelect(nEndTab+1) )
1864  ++nEndTab;
1865 
1866  aLocalSource.aStart.SetTab( nStartTab );
1867  aLocalSource.aEnd.SetTab( nEndTab );
1868  aLocalDest.SetTab( nStartTab );
1869 
1870  bSuccess = pDocSh->GetDocFunc().MoveBlock(
1871  aLocalSource, aLocalDest, bCut, true/*bRecord*/, true/*bPaint*/, true/*bApi*/ );
1872 
1873  nStartTab = nEndTab + 1;
1874  }
1875  }
1876 
1877  pDocSh->GetUndoManager()->LeaveListAction();
1878  }
1879  else
1880  {
1881  // move the block as specified
1882  bSuccess = pDocSh->GetDocFunc().MoveBlock(
1883  rSource, rDestPos, bCut, true/*bRecord*/, true/*bPaint*/, true/*bApi*/ );
1884  }
1885 
1886  ShowAllCursors();
1887  if (bSuccess)
1888  {
1889  // mark destination range
1890  ScAddress aDestEnd(
1891  rDestPos.Col() + rSource.aEnd.Col() - rSource.aStart.Col(),
1892  rDestPos.Row() + rSource.aEnd.Row() - rSource.aStart.Row(),
1893  nDestTab );
1894 
1895  bool bIncludeFiltered = bCut;
1896  if ( !bIncludeFiltered )
1897  {
1898  // find number of non-filtered rows
1899  SCROW nPastedCount = pDocSh->GetDocument().CountNonFilteredRows(
1900  rSource.aStart.Row(), rSource.aEnd.Row(), rSource.aStart.Tab());
1901 
1902  if ( nPastedCount == 0 )
1903  nPastedCount = 1;
1904  aDestEnd.SetRow( rDestPos.Row() + nPastedCount - 1 );
1905  }
1906 
1907  MarkRange( ScRange( rDestPos, aDestEnd ), false );
1908 
1909  pDocSh->UpdateOle(GetViewData());
1910  SelectionChanged();
1911  }
1912  return bSuccess;
1913 }
1914 
1915 // link inside the doc
1916 
1917 bool ScViewFunc::LinkBlock( const ScRange& rSource, const ScAddress& rDestPos )
1918 {
1919  // check overlapping
1920 
1921  if ( rSource.aStart.Tab() == rDestPos.Tab() )
1922  {
1923  SCCOL nDestEndCol = rDestPos.Col() + ( rSource.aEnd.Col() - rSource.aStart.Col() );
1924  SCROW nDestEndRow = rDestPos.Row() + ( rSource.aEnd.Row() - rSource.aStart.Row() );
1925 
1926  if ( rSource.aStart.Col() <= nDestEndCol && rDestPos.Col() <= rSource.aEnd.Col() &&
1927  rSource.aStart.Row() <= nDestEndRow && rDestPos.Row() <= rSource.aEnd.Row() )
1928  {
1929  return false;
1930  }
1931  }
1932 
1933  // run with paste
1934 
1935  ScDocument& rDoc = GetViewData().GetDocument();
1937  rDoc.CopyTabToClip( rSource.aStart.Col(), rSource.aStart.Row(),
1938  rSource.aEnd.Col(), rSource.aEnd.Row(),
1939  rSource.aStart.Tab(), pClipDoc.get() );
1940 
1941  // mark destination area (set cursor, no marks)
1942 
1943  if ( GetViewData().GetTabNo() != rDestPos.Tab() )
1944  SetTabNo( rDestPos.Tab() );
1945 
1946  MoveCursorAbs( rDestPos.Col(), rDestPos.Row(), SC_FOLLOW_NONE, false, false );
1947 
1948  // Paste
1949 
1950  PasteFromClip( InsertDeleteFlags::ALL, pClipDoc.get(), ScPasteFunc::NONE, false, false, true ); // as a link
1951 
1952  return true;
1953 }
1954 
1956  SCROW nStartRow , SCCOL nStartCol ,
1957  SCROW nEndRow , SCCOL nEndCol ,
1958  std::vector<std::unique_ptr<ScDataFormFragment>>& rEdits,
1959  sal_uInt16 aColLength )
1960 {
1961  ScDocument& rDoc = GetViewData().GetDocument();
1962  ScDocShell* pDocSh = GetViewData().GetDocShell();
1963  ScMarkData& rMark = GetViewData().GetMarkData();
1964  ScDocShellModificator aModificator( *pDocSh );
1965  SfxUndoManager* pUndoMgr = pDocSh->GetUndoManager();
1966 
1967  const bool bRecord( rDoc.IsUndoEnabled());
1968  ScDocumentUniquePtr pUndoDoc;
1969  ScDocumentUniquePtr pRedoDoc;
1970  std::unique_ptr<ScRefUndoData> pUndoData;
1971  SCTAB nTab = GetViewData().GetTabNo();
1972  SCTAB nStartTab = nTab;
1973  SCTAB nEndTab = nTab;
1974 
1975  {
1976  ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
1977  if ( pChangeTrack )
1978  pChangeTrack->ResetLastCut(); // no more cut-mode
1979  }
1980  ScRange aUserRange( nStartCol, nCurrentRow, nStartTab, nEndCol, nCurrentRow, nEndTab );
1981  bool bColInfo = ( nStartRow==0 && nEndRow==rDoc.MaxRow() );
1982  bool bRowInfo = ( nStartCol==0 && nEndCol==rDoc.MaxCol() );
1983  SCCOL nUndoEndCol = nStartCol+aColLength-1;
1984  SCROW nUndoEndRow = nCurrentRow;
1985 
1986  if ( bRecord )
1987  {
1988  pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1989  pUndoDoc->InitUndoSelected( rDoc , rMark , bColInfo , bRowInfo );
1990  rDoc.CopyToDocument( aUserRange , InsertDeleteFlags::VALUE , false, *pUndoDoc );
1991  }
1992  sal_uInt16 nExtFlags = 0;
1993  pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab , nEndCol, nEndRow, nEndTab ); // content before the change
1994  rDoc.BeginDrawUndo();
1995 
1996  for(sal_uInt16 i = 0; i < aColLength; i++)
1997  {
1998  if (rEdits[i] != nullptr)
1999  {
2000  OUString aFieldName = rEdits[i]->m_xEdit->get_text();
2001  rDoc.SetString( nStartCol + i, nCurrentRow, nTab, aFieldName );
2002  }
2003  }
2004  pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nCurrentRow, nStartTab, nEndCol, nCurrentRow, nEndTab ); // content after the change
2005  std::unique_ptr<SfxUndoAction> pUndo( new ScUndoDataForm( pDocSh,
2006  nStartCol, nCurrentRow, nStartTab,
2007  nUndoEndCol, nUndoEndRow, nEndTab, rMark,
2008  std::move(pUndoDoc), std::move(pRedoDoc),
2009  std::move(pUndoData) ) );
2010  pUndoMgr->AddUndoAction( std::make_unique<ScUndoWrapper>( std::move(pUndo) ), true );
2011 
2013  if (bColInfo)
2014  {
2015  nPaint |= PaintPartFlags::Top;
2016  nUndoEndCol = rDoc.MaxCol(); // just for drawing !
2017  }
2018  if (bRowInfo)
2019  {
2020  nPaint |= PaintPartFlags::Left;
2021  nUndoEndRow = rDoc.MaxRow(); // just for drawing !
2022  }
2023 
2024  pDocSh->PostPaint(
2025  ScRange(nStartCol, nCurrentRow, nStartTab, nUndoEndCol, nUndoEndRow, nEndTab),
2026  nPaint, nExtFlags);
2027  pDocSh->UpdateOle(GetViewData());
2028 }
2029 
2030 /* 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:3047
void BeginDrawUndo()
Definition: documen9.cxx:60
#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:231
static const com::sun::star::uno::Sequence< sal_Int8 > & getUnoTunnelId()
Definition: transobj.cxx:909
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:5659
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:3162
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
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:2047
void readGraphic(Graphic &rGraphic)
HasAttrFlags
Definition: global.hxx:192
bool PasteFromClipToMultiRanges(InsertDeleteFlags nFlags, ScDocument *pClipDoc, ScPasteFunc nFunction, bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs, InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags)
Definition: viewfun3.cxx:1638
Sheet / outlining (grouping) information.
SCROW Row() const
Definition: address.hxx:261
OUString GetTitle(sal_uInt16 nMaxLen=0) const
void MarkToMulti()
Definition: markdata.cxx:224
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:2790
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:2320
static SfxObjectShell * SetDrawClipDoc(bool bAnyOle)
Definition: transobj.cxx:812
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
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:37
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:3007
#define SO3_SW_CLASSID
void setSourceDocID(sal_uInt32 nVal)
Definition: clipparam.hxx:65
ScAddress aEnd
Definition: address.hxx:500
ScSplitPos GetActivePart() const
Definition: viewdata.hxx:397
Direction meDirection
Definition: clipparam.hxx:34
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
css::uno::Reference< css::frame::XModel > GetModel() const
void SetClipOptions(std::unique_ptr< ScClipOptions > pClipOptions)
Definition: documen3.cxx:2026
void FillTransferableObjectDescriptor(TransferableObjectDescriptor &rDesc) const
bool HasFormat(SotClipboardFormatId nFormat) const
void GetClipArea(SCCOL &nClipX, SCROW &nClipY, bool bIncludeFiltered)
Definition: document.cxx:3110
SC_DLLPUBLIC bool HasAttrib(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, HasAttrFlags nMask) const
Definition: document.cxx:5166
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:3200
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:2806
RET_NO
static UITestLogger & getInstance()
void logEvent(const EventDescription &rDescription)
static void SetGlobalDrawPersist(SfxObjectShell *pPersist)
Definition: drwlayer.cxx:2644
RET_YES
SC_DLLPUBLIC void CutToClip()
Not used?
Definition: viewfun3.cxx:89
void PostPasteFromClip(const ScRangeList &rPasteRanges, const ScMarkData &rMark)
Definition: viewfun3.cxx:1801
bool CopyToClipSingleRange(ScDocument *pClipDoc, const ScRangeList &rRanges, bool bCut, bool bIncludeObjects)
Definition: viewfun3.cxx:216
ScClipParam & GetClipParam()
Definition: document.cxx:2541
void UpdatePaintExt(sal_uInt16 &rExtFlags, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab)
Definition: docsh3.cxx:227
bool PasteOnDrawObjectLinked(const css::uno::Reference< css::datatransfer::XTransferable > &rxTransferable, SdrObject &rHitObj)
Definition: viewfun3.cxx:773
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:871
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:313
#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:195
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:2068
static TransferableDataHelper CreateFromSystemClipboard(vcl::Window *pWindow)
void push_back(const ScRange &rRange)
Definition: rangelst.cxx:1142
SC_DLLPUBLIC bool HasTable(SCTAB nTab) const
Definition: document.cxx:190
SCTAB Tab() const
Definition: address.hxx:270
bool mbCutMode
Definition: clipparam.hxx:35
#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
sal_Int32 nHandle
ScChangeTrack * GetChangeTrack() const
Definition: document.hxx:2395
void CopyTabToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, ScDocument *pClipDoc)
Definition: document.cxx:2266
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:70
bool empty() const
Definition: rangelst.hxx:88
const char * GetMessageId() const
Definition: editable.cxx:152
ScPasteFunc
Definition: global.hxx:188
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:3355
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:3179
#define SFX_TITLE_FULLNAME
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1057
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:870
T * get() const
virtual void AddUndoAction(std::unique_ptr< SfxUndoAction > pAction, bool bTryMerg=false)
sal_uInt32 getSourceDocID() const
Definition: clipparam.hxx:64
SCROW CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:4539
static void SetClipDocName(const OUString &rNew)
Definition: global.cxx:483
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:2314
bool LinkBlock(const ScRange &rSource, const ScAddress &rDestPos)
Definition: viewfun3.cxx:1917
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:478
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:2616
css::uno::Reference< css::datatransfer::XTransferable > GetXTransferable() const
sal_Int16 SCCOL
Definition: types.hxx:21
void DeleteSelection(InsertDeleteFlags nDelFlag, const ScMarkData &rMark, bool bBroadcast=true)
Definition: document.cxx:5919
InsertDeleteFlags
Definition: global.hxx:157
bool ValidCol(SCCOL nCol) const
Definition: document.hxx:873
static tools::SvRef< ScDocShell > xDrawClipDocShellRef
Definition: global.hxx:580
#define SC_MOD()
Definition: scmod.hxx:249
const SdrPage * GetPage(sal_uInt16 nPgNum) const
size_t size() const
Definition: rangelst.hxx:89
static OUString CreateShellID(const SfxObjectShell *pShell)
OUString ScResId(const char *pId)
Definition: scdll.cxx:89
ScMarkType GetSimpleArea(SCCOL &rStartCol, SCROW &rStartRow, SCTAB &rStartTab, SCCOL &rEndCol, SCROW &rEndRow, SCTAB &rEndTab) const
Definition: viewdata.cxx:1171
bool IsCutMode()
Definition: document.cxx:2057
ScGridWindow * GetActiveWin()
Definition: viewdata.cxx:3063
ScPasteFunc nFunction
Definition: undoblk.hxx:165
bool PasteMultiRangesFromClip(InsertDeleteFlags nFlags, ScDocument *pClipDoc, ScPasteFunc nFunction, bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs, InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags)
Definition: viewfun3.cxx:1473
bool MoveBlockTo(const ScRange &rSource, const ScAddress &rDestPos, bool bCut)
Definition: viewfun3.cxx:1832
iterator end()
Definition: markdata.cxx:953
bool IsEditable() const
Definition: editable.hxx:83
bool IsBlockEmpty(SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, bool bIgnoreNotes=false) const
Definition: document.cxx:5283
void GetVars(SCCOL &nCol1, SCROW &nRow1, SCTAB &nTab1, SCCOL &nCol2, SCROW &nRow2, SCTAB &nTab2) const
Definition: address.hxx:692
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:5394
ScRangeList maRanges
Definition: clipparam.hxx:33
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
Definition: docsh3.cxx:100
SC_DLLPUBLIC bool ExtendMerge(SCCOL nStartCol, SCROW nStartRow, SCCOL &rEndCol, SCROW &rEndRow, SCTAB nTab, bool bRefresh=false)
Definition: document.cxx:5555
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:876
sal_uInt32 GetDocumentID() const
an ID unique to each document instance
Definition: documen2.cxx:254
SCCOL Col() const
Definition: address.hxx:266
size_t LeaveListAction()
ScAddress GetCurPos() const
Definition: viewdata.cxx:4008
bool CopyToClipMultiRange(const ScDocument *pClipDoc, const ScRangeList &rRanges, bool bCut, bool bApi, bool bIncludeObjects)
Definition: viewfun3.cxx:306
Point PixelToLogic(const Point &rDevicePt) const
bool IsMerged() const
Definition: attrib.hxx:71
ScModelObj * getMustPropagateChangesModel(const ScDocShell &rDocShell)
Definition: docsh.hxx:470
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:948
sal_Int32 SCROW
Definition: types.hxx:17
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:874
const OUString & GetShellID() const
Definition: drwtrans.cxx:638
unsigned char sal_uInt8
void ExtendMergeSel(SCCOL nStartCol, SCROW nStartRow, SCCOL &rEndCol, SCROW &rEndRow, const ScMarkData &rMark, bool bRefresh=false)
Definition: document.cxx:5527
#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:832
void PasteFromTransferable(const css::uno::Reference< css::datatransfer::XTransferable > &rxTransferable)
Definition: viewfun3.cxx:620
bool DoInitNew(SfxMedium *pMedium=nullptr)
InsCellCmd
Definition: global.hxx:298
bool GetBitmapEx(SotClipboardFormatId nFormat, BitmapEx &rBmp)
static SC_DLLPUBLIC ScTransferObj * GetOwnClipboard(const css::uno::Reference< css::datatransfer::XTransferable2 > &)
Definition: transobj.cxx:193
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:1955
void * p
static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId()
Definition: drwtrans.cxx:738
#define EXCHG_OUT_ACTION_INSERT_SVXB
const ScPatternAttr * GetNext(SCCOL &rCol, SCROW &rRow1, SCROW &rRow2)
Definition: dociter.cxx:2660
#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:1115
OUString GetURLNoPass(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
void SetDocumentModified()
Definition: docsh.cxx:3159
ScRange & front()
Definition: rangelst.hxx:92
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1056
bool GetTransferableObjectDescriptor(SotClipboardFormatId nFormat, TransferableObjectDescriptor &rDesc)
bool IsUndoEnabled() const
Definition: document.hxx:1533
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:184
std::map< OUString, OUString > aParameters
PaintPartFlags
Definition: global.hxx:118
This struct stores general clipboard parameters associated with a ScDocument instance created in clip...
Definition: clipparam.hxx:29
SC_DLLPUBLIC void ExtendOverlapped(SCCOL &rStartCol, SCROW &rStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:5465
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:915
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:451
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:2167
SCCOL GetCurX() const
Definition: viewdata.hxx:400
bool isMultiRange() const
Definition: clipparam.cxx:38
const DataFlavorExVector & GetDataFlavorExVector() const
SfxMedium * GetMedium() const