1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "scitems.hxx"
21 #include <svx/svdetc.hxx>
22 #include <svx/svditer.hxx>
23 #include <svx/svdoole2.hxx>
24 #include <svx/svdpage.hxx>
25 #include <sfx2/dispatch.hxx>
26 #include <sfx2/docfile.hxx>
27 #include <svl/stritem.hxx>
28 #include <svl/ptitem.hxx>
29 #include <svl/urlbmk.hxx>
30 #include <comphelper/classids.hxx>
31 #include <sot/formats.hxx>
32 #include <sot/storage.hxx>
33 #include <vcl/graph.hxx>
34 #include <vcl/virdev.hxx>
35 #include <vcl/msgbox.hxx>
36 #include <tools/urlobj.hxx>
37 #include <sot/exchange.hxx>
41 #include "patattr.hxx"
42 #include "dociter.hxx"
43 #include "viewfunc.hxx"
44 #include "tabvwsh.hxx"
46 #include "docfunc.hxx"
47 #include "undoblk.hxx"
48 #include "refundo.hxx"
49 #include "globstr.hrc"
51 #include "transobj.hxx"
52 #include "drwtrans.hxx"
53 #include "rangenam.hxx"
56 #include "chgtrack.hxx"
57 #include "waitoff.hxx"
60 #include "inputopt.hxx"
61 #include "warnbox.hxx"
62 #include "drwlayer.hxx"
63 #include "editable.hxx"
65 #include "clipparam.hxx"
66 #include "undodat.hxx"
67 #include "drawview.hxx"
68 #include "cliputil.hxx"
69 #include <gridwin.hxx>
70 #include <boost/scoped_ptr.hpp>
72 using namespace com::sun::star
;
74 // STATIC DATA ---------------------------------------------------------------
76 // GlobalName of writer-DocShell from comphelper/classids.hxx
80 void ScViewFunc::CutToClip( ScDocument
* pClipDoc
, bool bIncludeObjects
)
84 ScEditableTester
aTester( this );
85 if (!aTester
.IsEditable()) // selection editable?
87 ErrorMessage( aTester
.GetMessageId() );
91 ScRange aRange
; // delete this range
92 if ( GetViewData().GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
94 ScDocument
* pDoc
= GetViewData().GetDocument();
95 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
96 ScMarkData
& rMark
= GetViewData().GetMarkData();
97 const bool bRecord(pDoc
->IsUndoEnabled()); // Undo/Redo
99 ScDocShellModificator
aModificator( *pDocSh
);
101 if ( !rMark
.IsMarked() && !rMark
.IsMultiMarked() ) // mark the range if not marked yet
105 rMark
.SetMarkArea( aRange
);
109 CopyToClip( pClipDoc
, true, false, bIncludeObjects
); // copy to clipboard
111 ScAddress
aOldEnd( aRange
.aEnd
); // combined cells in this range?
112 pDoc
->ExtendMerge( aRange
, true );
114 ScDocument
* pUndoDoc
= NULL
;
117 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
118 pUndoDoc
->InitUndoSelected( pDoc
, rMark
);
119 // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
120 ScRange aCopyRange
= aRange
;
121 aCopyRange
.aStart
.SetTab(0);
122 aCopyRange
.aEnd
.SetTab(pDoc
->GetTableCount()-1);
123 pDoc
->CopyToDocument( aCopyRange
, (IDF_ALL
& ~IDF_OBJECTS
) | IDF_NOCAPTIONS
, false, pUndoDoc
);
124 pDoc
->BeginDrawUndo();
127 sal_uInt16 nExtFlags
= 0;
128 pDocSh
->UpdatePaintExt( nExtFlags
, aRange
);
131 pDoc
->DeleteSelection( IDF_ALL
, rMark
);
132 if ( bIncludeObjects
)
133 pDoc
->DeleteObjectsInSelection( rMark
);
134 rMark
.MarkToSimple();
136 if ( !AdjustRowHeight( aRange
.aStart
.Row(), aRange
.aEnd
.Row() ) )
137 pDocSh
->PostPaint( aRange
, PAINT_GRID
, nExtFlags
);
139 if ( bRecord
) // Draw-Undo now available
140 pDocSh
->GetUndoManager()->AddUndoAction(
141 new ScUndoCut( pDocSh
, aRange
, aOldEnd
, rMark
, pUndoDoc
) );
143 aModificator
.SetDocumentModified();
144 pDocSh
->UpdateOle(&GetViewData());
146 CellContentChanged();
149 ErrorMessage( STR_NOMULTISELECT
);
154 bool ScViewFunc::CopyToClip( ScDocument
* pClipDoc
, bool bCut
, bool bApi
, bool bIncludeObjects
, bool bStopEdit
)
157 ScMarkType eMarkType
= GetViewData().GetSimpleArea( aRange
);
158 ScMarkData
& rMark
= GetViewData().GetMarkData();
161 if ( eMarkType
== SC_MARK_SIMPLE
|| eMarkType
== SC_MARK_SIMPLE_FILTERED
)
163 ScRangeList aRangeList
;
164 aRangeList
.Append( aRange
);
165 bDone
= CopyToClip( pClipDoc
, aRangeList
, bCut
, bApi
, bIncludeObjects
, bStopEdit
, false );
167 else if (eMarkType
== SC_MARK_MULTI
)
169 ScRangeList aRangeList
;
170 rMark
.MarkToSimple();
171 rMark
.FillRangeListWithMarks(&aRangeList
, false);
172 bDone
= CopyToClip( pClipDoc
, aRangeList
, bCut
, bApi
, bIncludeObjects
, bStopEdit
, false );
177 ErrorMessage(STR_NOMULTISELECT
);
183 // Copy the content of the Range into clipboard.
184 bool ScViewFunc::CopyToClip( ScDocument
* pClipDoc
, const ScRangeList
& rRanges
, bool bCut
, bool bApi
, bool bIncludeObjects
, bool bStopEdit
, bool bUseRangeForVBA
)
186 if ( rRanges
.empty() )
192 ScRange aRange
= *rRanges
[0];
193 ScClipParam
aClipParam( aRange
, bCut
);
194 aClipParam
.maRanges
= rRanges
;
196 ScDocument
* pDoc
= GetViewData().GetDocument();
197 ScMarkData
& rMark
= GetViewData().GetMarkData();
199 if ( !aClipParam
.isMultiRange() )
201 if ( pDoc
&& ( !pDoc
->HasSelectedBlockMatrixFragment( aRange
.aStart
.Col(), aRange
.aStart
.Row(), aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), rMark
) ) )
203 bool bSysClip
= false;
204 if ( !pClipDoc
) // no clip doc specified
206 // Create one (deleted by ScTransferObj).
207 pClipDoc
= new ScDocument( SCDOCMODE_CLIP
);
208 bSysClip
= true; // and copy into system
212 ScChangeTrack
* pChangeTrack
= pDoc
->GetChangeTrack();
214 pChangeTrack
->ResetLastCut();
217 if ( bSysClip
&& bIncludeObjects
)
219 bool bAnyOle
= pDoc
->HasOLEObjectsInArea( aRange
);
220 // Update ScGlobal::pDrawClipDocShellRef.
221 ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle
) );
224 if ( !bUseRangeForVBA
)
225 // is this necessary?, will setting the doc id upset the
226 // following paste operation with range? would be nicer to just set this always
227 // and lose the 'if' above
228 aClipParam
.setSourceDocID( pDoc
->GetDocumentID() );
230 pDoc
->CopyToClip( aClipParam
, pClipDoc
, &rMark
, false, false, bIncludeObjects
, true, bUseRangeForVBA
);
231 if ( !bUseRangeForVBA
&& pDoc
&& pClipDoc
)
233 ScDrawLayer
* pDrawLayer
= pClipDoc
->GetDrawLayer();
236 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
237 ScRangeListVector
& rRangesVector
= rClipParam
.maProtectedChartRangesVector
;
238 SCTAB nTabCount
= pClipDoc
->GetTableCount();
239 for ( SCTAB nTab
= 0; nTab
< nTabCount
; ++nTab
)
241 SdrPage
* pPage
= pDrawLayer
->GetPage( static_cast< sal_uInt16
>( nTab
) );
244 ScChartHelper::FillProtectedChartRangesVector( rRangesVector
, pDoc
, pPage
);
252 ScDrawLayer::SetGlobalDrawPersist(NULL
);
253 ScGlobal::SetClipDocName( pDoc
->GetDocumentShell()->GetTitle( SFX_TITLE_FULLNAME
) );
255 pClipDoc
->ExtendMerge( aRange
, true );
259 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
260 TransferableObjectDescriptor aObjDesc
;
261 pDocSh
->FillTransferableObjectDescriptor( aObjDesc
);
262 aObjDesc
.maDisplayName
= pDocSh
->GetMedium()->GetURLObject().GetURLNoPass();
263 // maSize is set in ScTransferObj ctor
265 ScTransferObj
* pTransferObj
= new ScTransferObj( pClipDoc
, aObjDesc
);
266 uno::Reference
<datatransfer::XTransferable
> xTransferable( pTransferObj
);
267 if ( ScGlobal::pDrawClipDocShellRef
)
269 SfxObjectShellRef
aPersistRef( &(*ScGlobal::pDrawClipDocShellRef
) );
270 pTransferObj
->SetDrawPersist( aPersistRef
);// keep persist for ole objects alive
273 pTransferObj
->CopyToClipboard( GetActiveWin() );
274 SC_MOD()->SetClipObject( pTransferObj
, NULL
);
282 bool bSuccess
= false;
283 aClipParam
.mbCutMode
= false;
288 // We con't support cutting of multi-selections.
292 // TODO: What's this for?
295 ::std::unique_ptr
<ScDocument
> pDocClip(new ScDocument(SCDOCMODE_CLIP
));
297 // Check for geometrical feasibility of the ranges.
298 bool bValidRanges
= true;
299 ScRange
* p
= aClipParam
.maRanges
.front();
300 SCCOL nPrevColDelta
= 0;
301 SCROW nPrevRowDelta
= 0;
302 SCCOL nPrevCol
= p
->aStart
.Col();
303 SCROW nPrevRow
= p
->aStart
.Row();
304 SCCOL nPrevColSize
= p
->aEnd
.Col() - p
->aStart
.Col() + 1;
305 SCROW nPrevRowSize
= p
->aEnd
.Row() - p
->aStart
.Row() + 1;
306 for ( size_t i
= 1; i
< aClipParam
.maRanges
.size(); ++i
)
308 p
= aClipParam
.maRanges
[i
];
309 if ( pDoc
->HasSelectedBlockMatrixFragment(
310 p
->aStart
.Col(), p
->aStart
.Row(), p
->aEnd
.Col(), p
->aEnd
.Row(), rMark
) )
313 ErrorMessage(STR_MATRIXFRAGMENTERR
);
317 SCCOL nColDelta
= p
->aStart
.Col() - nPrevCol
;
318 SCROW nRowDelta
= p
->aStart
.Row() - nPrevRow
;
320 if ((nColDelta
&& nRowDelta
) || (nPrevColDelta
&& nRowDelta
) || (nPrevRowDelta
&& nColDelta
))
322 bValidRanges
= false;
326 if (aClipParam
.meDirection
== ScClipParam::Unspecified
)
329 aClipParam
.meDirection
= ScClipParam::Column
;
331 aClipParam
.meDirection
= ScClipParam::Row
;
334 SCCOL nColSize
= p
->aEnd
.Col() - p
->aStart
.Col() + 1;
335 SCROW nRowSize
= p
->aEnd
.Row() - p
->aStart
.Row() + 1;
337 if (aClipParam
.meDirection
== ScClipParam::Column
&& nRowSize
!= nPrevRowSize
)
339 // column-oriented ranges must have identical row size.
340 bValidRanges
= false;
343 if (aClipParam
.meDirection
== ScClipParam::Row
&& nColSize
!= nPrevColSize
)
345 // likewise, row-oriented ranges must have identical
347 bValidRanges
= false;
351 nPrevCol
= p
->aStart
.Col();
352 nPrevRow
= p
->aStart
.Row();
353 nPrevColDelta
= nColDelta
;
354 nPrevRowDelta
= nRowDelta
;
355 nPrevColSize
= nColSize
;
356 nPrevRowSize
= nRowSize
;
360 pDoc
->CopyToClip(aClipParam
, pDocClip
.get(), &rMark
, false, false, bIncludeObjects
, true, bUseRangeForVBA
);
362 ScChangeTrack
* pChangeTrack
= pDoc
->GetChangeTrack();
364 pChangeTrack
->ResetLastCut(); // no more cut-mode
367 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
368 TransferableObjectDescriptor aObjDesc
;
369 pDocSh
->FillTransferableObjectDescriptor( aObjDesc
);
370 aObjDesc
.maDisplayName
= pDocSh
->GetMedium()->GetURLObject().GetURLNoPass();
371 // maSize is set in ScTransferObj ctor
373 ScTransferObj
* pTransferObj
= new ScTransferObj( pDocClip
.release(), aObjDesc
);
374 uno::Reference
<datatransfer::XTransferable
> xTransferable( pTransferObj
);
376 if ( ScGlobal::pDrawClipDocShellRef
)
378 SfxObjectShellRef
aPersistRef( &(*ScGlobal::pDrawClipDocShellRef
) );
379 pTransferObj
->SetDrawPersist( aPersistRef
); // keep persist for ole objects alive
382 pTransferObj
->CopyToClipboard( GetActiveWin() ); // system clipboard
383 SC_MOD()->SetClipObject( pTransferObj
, NULL
); // internal clipboard
390 if (!bSuccess
&& !bApi
)
391 ErrorMessage(STR_NOMULTISELECT
);
399 ScTransferObj
* ScViewFunc::CopyToTransferable()
402 if ( GetViewData().GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
404 ScDocument
* pDoc
= GetViewData().GetDocument();
405 ScMarkData
& rMark
= GetViewData().GetMarkData();
406 if ( !pDoc
->HasSelectedBlockMatrixFragment(
407 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
408 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(),
411 ScDocument
*pClipDoc
= new ScDocument( SCDOCMODE_CLIP
); // create one (deleted by ScTransferObj)
413 bool bAnyOle
= pDoc
->HasOLEObjectsInArea( aRange
, &rMark
);
414 ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle
) );
416 ScClipParam
aClipParam(aRange
, false);
417 pDoc
->CopyToClip(aClipParam
, pClipDoc
, &rMark
, false, false, true);
419 ScDrawLayer::SetGlobalDrawPersist(NULL
);
420 pClipDoc
->ExtendMerge( aRange
, true );
422 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
423 TransferableObjectDescriptor aObjDesc
;
424 pDocSh
->FillTransferableObjectDescriptor( aObjDesc
);
425 aObjDesc
.maDisplayName
= pDocSh
->GetMedium()->GetURLObject().GetURLNoPass();
426 ScTransferObj
* pTransferObj
= new ScTransferObj( pClipDoc
, aObjDesc
);
436 void ScViewFunc::PasteDraw()
438 ScViewData
& rViewData
= GetViewData();
439 SCCOL nPosX
= rViewData
.GetCurX();
440 SCROW nPosY
= rViewData
.GetCurY();
441 vcl::Window
* pWin
= GetActiveWin();
442 Point aPos
= pWin
->PixelToLogic( rViewData
.GetScrPos( nPosX
, nPosY
,
443 rViewData
.GetActivePart() ) );
444 ScDrawTransferObj
* pDrawClip
= ScDrawTransferObj::GetOwnClipboard( pWin
);
447 OUString aSrcShellID
= pDrawClip
->GetShellID();
448 OUString aDestShellID
= SfxObjectShell::CreateShellID(rViewData
.GetDocShell());
449 PasteDraw(aPos
, pDrawClip
->GetModel(), false, aSrcShellID
, aDestShellID
);
453 void ScViewFunc::PasteFromSystem()
457 vcl::Window
* pWin
= GetActiveWin();
458 ScTransferObj
* pOwnClip
= ScTransferObj::GetOwnClipboard( pWin
);
459 ScDrawTransferObj
* pDrawClip
= ScDrawTransferObj::GetOwnClipboard( pWin
);
463 // keep a reference in case the clipboard is changed during PasteFromClip
464 uno::Reference
<datatransfer::XTransferable
> aOwnClipRef( pOwnClip
);
465 PasteFromClip( IDF_ALL
, pOwnClip
->GetDocument(),
466 PASTE_NOFUNC
, false, false, false, INS_NONE
, IDF_NONE
,
467 true ); // allow warning dialog
473 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin
) );
476 SotClipboardFormatId nBiff8
= SotExchange::RegisterFormatName(OUString("Biff8"));
477 SotClipboardFormatId nBiff5
= SotExchange::RegisterFormatName(OUString("Biff5"));
479 SotExchangeDest nDestination
= SotExchangeDest::SCDOC_FREE_AREA
;
480 sal_uInt16 nSourceOptions
= EXCHG_IN_ACTION_COPY
;
481 SotClipboardFormatId nFormat
; // output param for GetExchangeAction
482 sal_uInt16 nEventAction
; // output param for GetExchangeAction
484 uno::Reference
<com::sun::star::datatransfer::XTransferable
> xTransferable( aDataHelper
.GetXTransferable() );
485 sal_uInt16 nAction
= SotExchange::GetExchangeAction(
486 aDataHelper
.GetDataFlavorExVector(),
489 EXCHG_IN_ACTION_DEFAULT
,
490 nFormat
, nEventAction
, SotClipboardFormatId::NONE
,
493 if ( nAction
!= EXCHG_INOUT_ACTION_NONE
)
495 nAction
= ( nAction
& EXCHG_ACTION_MASK
);
499 case EXCHG_OUT_ACTION_INSERT_SVXB
:
500 case EXCHG_OUT_ACTION_INSERT_GDIMETAFILE
:
501 case EXCHG_OUT_ACTION_INSERT_BITMAP
:
502 case EXCHG_OUT_ACTION_INSERT_GRAPH
:
503 // SotClipboardFormatId::BITMAP
504 // SotClipboardFormatId::PNG
505 // SotClipboardFormatId::GDIMETAFILE
506 // SotClipboardFormatId::SVXB
507 PasteFromSystem(nFormat
);
510 nAction
= EXCHG_INOUT_ACTION_NONE
;
514 if ( nAction
== EXCHG_INOUT_ACTION_NONE
)
516 // first SvDraw-model, then drawing
517 // (only one drawing is allowed)
519 if (aDataHelper
.HasFormat( SotClipboardFormatId::DRAWING
))
521 // special case for tables from drawing
522 if( aDataHelper
.HasFormat( SotClipboardFormatId::RTF
) )
524 PasteFromSystem( SotClipboardFormatId::RTF
);
528 PasteFromSystem( SotClipboardFormatId::DRAWING
);
531 else if (aDataHelper
.HasFormat( SotClipboardFormatId::EMBED_SOURCE
))
533 // If it's a Writer object, insert RTF instead of OLE
535 // Else, if the class id is all-zero, and SYLK is available,
536 // it probably is spreadsheet cells that have been put
537 // on the clipboard by OOo, so use the SYLK. (fdo#31077)
540 TransferableObjectDescriptor aObjDesc
;
541 if( aDataHelper
.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR
, aObjDesc
) )
543 bDoRtf
= ( ( aObjDesc
.maClassName
== SvGlobalName( SO3_SW_CLASSID
) ||
544 aObjDesc
.maClassName
== SvGlobalName( SO3_SWWEB_CLASSID
) )
545 && aDataHelper
.HasFormat( SotClipboardFormatId::RTF
) );
548 PasteFromSystem( SotClipboardFormatId::RTF
);
549 else if ( aObjDesc
.maClassName
== SvGlobalName( 0,0,0,0,0,0,0,0,0,0,0 )
550 && aDataHelper
.HasFormat( SotClipboardFormatId::SYLK
))
551 PasteFromSystem( SotClipboardFormatId::SYLK
);
553 PasteFromSystem( SotClipboardFormatId::EMBED_SOURCE
);
555 else if (aDataHelper
.HasFormat( SotClipboardFormatId::LINK_SOURCE
))
556 PasteFromSystem( SotClipboardFormatId::LINK_SOURCE
);
557 // the following format can not affect scenario from #89579#
558 else if (aDataHelper
.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ_OLE
))
559 PasteFromSystem( SotClipboardFormatId::EMBEDDED_OBJ_OLE
);
560 // SotClipboardFormatId::PRIVATE no longer here (can't work if pOwnClip is NULL)
561 else if (aDataHelper
.HasFormat(nBiff8
)) // before xxx_OLE formats
562 PasteFromSystem(nBiff8
);
563 else if (aDataHelper
.HasFormat(nBiff5
))
564 PasteFromSystem(nBiff5
);
565 else if (aDataHelper
.HasFormat(SotClipboardFormatId::RTF
))
566 PasteFromSystem(SotClipboardFormatId::RTF
);
567 else if (aDataHelper
.HasFormat(SotClipboardFormatId::HTML
))
568 PasteFromSystem(SotClipboardFormatId::HTML
);
569 else if (aDataHelper
.HasFormat(SotClipboardFormatId::HTML_SIMPLE
))
570 PasteFromSystem(SotClipboardFormatId::HTML_SIMPLE
);
571 else if (aDataHelper
.HasFormat(SotClipboardFormatId::SYLK
))
572 PasteFromSystem(SotClipboardFormatId::SYLK
);
573 else if (aDataHelper
.HasFormat(SotClipboardFormatId::STRING
))
574 PasteFromSystem(SotClipboardFormatId::STRING
);
575 // xxx_OLE formats come last, like in SotExchange tables
576 else if (aDataHelper
.HasFormat( SotClipboardFormatId::EMBED_SOURCE_OLE
))
577 PasteFromSystem( SotClipboardFormatId::EMBED_SOURCE_OLE
);
578 else if (aDataHelper
.HasFormat( SotClipboardFormatId::LINK_SOURCE_OLE
))
579 PasteFromSystem( SotClipboardFormatId::LINK_SOURCE_OLE
);
583 // no exception-> SID_PASTE has FastCall-flag from idl
584 // will be called in case of empty clipboard (#42531#)
587 void ScViewFunc::PasteFromTransferable( const uno::Reference
<datatransfer::XTransferable
>& rxTransferable
)
589 ScTransferObj
*pOwnClip
=0;
590 ScDrawTransferObj
*pDrawClip
=0;
591 uno::Reference
<lang::XUnoTunnel
> xTunnel( rxTransferable
, uno::UNO_QUERY
);
594 sal_Int64 nHandle
= xTunnel
->getSomething( ScTransferObj::getUnoTunnelId() );
596 pOwnClip
= reinterpret_cast<ScTransferObj
*>( (sal_IntPtr
) nHandle
);
599 nHandle
= xTunnel
->getSomething( ScDrawTransferObj::getUnoTunnelId() );
601 pDrawClip
= reinterpret_cast<ScDrawTransferObj
*>( (sal_IntPtr
) nHandle
);
607 PasteFromClip( IDF_ALL
, pOwnClip
->GetDocument(),
608 PASTE_NOFUNC
, false, false, false, INS_NONE
, IDF_NONE
,
609 true ); // allow warning dialog
613 ScViewData
& rViewData
= GetViewData();
614 SCCOL nPosX
= rViewData
.GetCurX();
615 SCROW nPosY
= rViewData
.GetCurY();
616 vcl::Window
* pWin
= GetActiveWin();
617 Point aPos
= pWin
->PixelToLogic( rViewData
.GetScrPos( nPosX
, nPosY
, rViewData
.GetActivePart() ) );
619 aPos
, pDrawClip
->GetModel(), false,
620 pDrawClip
->GetShellID(), SfxObjectShell::CreateShellID(rViewData
.GetDocShell()));
624 TransferableDataHelper
aDataHelper( rxTransferable
);
626 SotClipboardFormatId nBiff8
= SotExchange::RegisterFormatName(OUString("Biff8"));
627 SotClipboardFormatId nBiff5
= SotExchange::RegisterFormatName(OUString("Biff5"));
628 SotClipboardFormatId nFormatId
= SotClipboardFormatId::NONE
;
629 // first SvDraw-model, then drawing
630 // (only one drawing is allowed)
632 if (aDataHelper
.HasFormat( SotClipboardFormatId::DRAWING
))
633 nFormatId
= SotClipboardFormatId::DRAWING
;
634 else if (aDataHelper
.HasFormat( SotClipboardFormatId::SVXB
))
635 nFormatId
= SotClipboardFormatId::SVXB
;
636 else if (aDataHelper
.HasFormat( SotClipboardFormatId::EMBED_SOURCE
))
638 // If it's a Writer object, insert RTF instead of OLE
640 TransferableObjectDescriptor aObjDesc
;
641 if( aDataHelper
.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR
, aObjDesc
) )
643 bDoRtf
= ( ( aObjDesc
.maClassName
== SvGlobalName( SO3_SW_CLASSID
) ||
644 aObjDesc
.maClassName
== SvGlobalName( SO3_SWWEB_CLASSID
) )
645 && aDataHelper
.HasFormat( SotClipboardFormatId::RTF
) );
648 nFormatId
= SotClipboardFormatId::RTF
;
650 nFormatId
= SotClipboardFormatId::EMBED_SOURCE
;
652 else if (aDataHelper
.HasFormat( SotClipboardFormatId::LINK_SOURCE
))
653 nFormatId
= SotClipboardFormatId::LINK_SOURCE
;
654 // the following format can not affect scenario from #89579#
655 else if (aDataHelper
.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ_OLE
))
656 nFormatId
= SotClipboardFormatId::EMBEDDED_OBJ_OLE
;
657 // SotClipboardFormatId::PRIVATE no longer here (can't work if pOwnClip is NULL)
658 else if (aDataHelper
.HasFormat(nBiff8
)) // before xxx_OLE formats
660 else if (aDataHelper
.HasFormat(nBiff5
))
662 else if (aDataHelper
.HasFormat(SotClipboardFormatId::RTF
))
663 nFormatId
= SotClipboardFormatId::RTF
;
664 else if (aDataHelper
.HasFormat(SotClipboardFormatId::HTML
))
665 nFormatId
= SotClipboardFormatId::HTML
;
666 else if (aDataHelper
.HasFormat(SotClipboardFormatId::HTML_SIMPLE
))
667 nFormatId
= SotClipboardFormatId::HTML_SIMPLE
;
668 else if (aDataHelper
.HasFormat(SotClipboardFormatId::SYLK
))
669 nFormatId
= SotClipboardFormatId::SYLK
;
670 else if (aDataHelper
.HasFormat(SotClipboardFormatId::STRING
))
671 nFormatId
= SotClipboardFormatId::STRING
;
672 else if (aDataHelper
.HasFormat(SotClipboardFormatId::GDIMETAFILE
))
673 nFormatId
= SotClipboardFormatId::GDIMETAFILE
;
674 else if (aDataHelper
.HasFormat(SotClipboardFormatId::BITMAP
))
675 nFormatId
= SotClipboardFormatId::BITMAP
;
676 // xxx_OLE formats come last, like in SotExchange tables
677 else if (aDataHelper
.HasFormat( SotClipboardFormatId::EMBED_SOURCE_OLE
))
678 nFormatId
= SotClipboardFormatId::EMBED_SOURCE_OLE
;
679 else if (aDataHelper
.HasFormat( SotClipboardFormatId::LINK_SOURCE_OLE
))
680 nFormatId
= SotClipboardFormatId::LINK_SOURCE_OLE
;
684 PasteDataFormat( nFormatId
, aDataHelper
.GetTransferable(),
685 GetViewData().GetCurX(), GetViewData().GetCurY(),
686 NULL
, false, false );
691 bool ScViewFunc::PasteFromSystem( SotClipboardFormatId nFormatId
, bool bApi
)
696 vcl::Window
* pWin
= GetActiveWin();
697 ScTransferObj
* pOwnClip
= ScTransferObj::GetOwnClipboard( pWin
);
698 if ( nFormatId
== SotClipboardFormatId::NONE
&& pOwnClip
)
700 // keep a reference in case the clipboard is changed during PasteFromClip
701 uno::Reference
<datatransfer::XTransferable
> aOwnClipRef( pOwnClip
);
702 PasteFromClip( IDF_ALL
, pOwnClip
->GetDocument(),
703 PASTE_NOFUNC
, false, false, false, INS_NONE
, IDF_NONE
,
704 !bApi
); // allow warning dialog
708 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin
) );
709 if ( !aDataHelper
.GetTransferable().is() )
715 ScViewData
& rViewData
= GetViewData();
717 if ( rViewData
.GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
719 nPosX
= aRange
.aStart
.Col();
720 nPosY
= aRange
.aStart
.Row();
724 nPosX
= rViewData
.GetCurX();
725 nPosY
= rViewData
.GetCurY();
728 bRet
= PasteDataFormat( nFormatId
, aDataHelper
.GetTransferable(),
730 NULL
, false, !bApi
); // allow warning dialog
732 if ( !bRet
&& !bApi
)
733 ErrorMessage(STR_PASTE_ERROR
);
740 bool ScViewFunc::PasteOnDrawObjectLinked(
741 const uno::Reference
<datatransfer::XTransferable
>& rxTransferable
,
744 TransferableDataHelper
aDataHelper( rxTransferable
);
746 if ( aDataHelper
.HasFormat( SotClipboardFormatId::SVXB
) )
748 tools::SvRef
<SotStorageStream
> xStm
;
749 ScDrawView
* pScDrawView
= GetScDrawView();
751 if( pScDrawView
&& aDataHelper
.GetSotStorageStream( SotClipboardFormatId::SVXB
, xStm
) )
755 ReadGraphic( *xStm
, aGraphic
);
757 const OUString aEmpty
;
758 const OUString
aBeginUndo(ScGlobal::GetRscString(STR_UNDO_DRAGDROP
));
760 if(pScDrawView
->ApplyGraphicToObject( rHitObj
, aGraphic
, aBeginUndo
, aEmpty
, aEmpty
))
766 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::GDIMETAFILE
) )
769 ScDrawView
* pScDrawView
= GetScDrawView();
771 if( pScDrawView
&& aDataHelper
.GetGDIMetaFile( SotClipboardFormatId::GDIMETAFILE
, aMtf
) )
773 const OUString aEmpty
;
774 const OUString
aBeginUndo(ScGlobal::GetRscString(STR_UNDO_DRAGDROP
));
776 if(pScDrawView
->ApplyGraphicToObject( rHitObj
, Graphic(aMtf
), aBeginUndo
, aEmpty
, aEmpty
))
782 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::BITMAP
) || aDataHelper
.HasFormat( SotClipboardFormatId::PNG
) )
785 ScDrawView
* pScDrawView
= GetScDrawView();
787 if( pScDrawView
&& aDataHelper
.GetBitmapEx( SotClipboardFormatId::BITMAP
, aBmpEx
) )
789 const OUString aEmpty
;
790 const OUString
aBeginUndo(ScGlobal::GetRscString(STR_UNDO_DRAGDROP
));
792 if(pScDrawView
->ApplyGraphicToObject( rHitObj
, Graphic(aBmpEx
), aBeginUndo
, aEmpty
, aEmpty
))
802 static bool lcl_SelHasAttrib( ScDocument
* pDoc
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
803 const ScMarkData
& rTabSelection
, sal_uInt16 nMask
)
805 ScMarkData::const_iterator itr
= rTabSelection
.begin(), itrEnd
= rTabSelection
.end();
806 for (; itr
!= itrEnd
; ++itr
)
807 if ( pDoc
->HasAttrib( nCol1
, nRow1
, *itr
, nCol2
, nRow2
, *itr
, nMask
) )
818 bool checkDestRangeForOverwrite(const ScRangeList
& rDestRanges
, const ScDocument
* pDoc
, const ScMarkData
& rMark
, vcl::Window
* pParentWnd
)
820 bool bIsEmpty
= true;
821 ScMarkData::const_iterator itrTab
= rMark
.begin(), itrTabEnd
= rMark
.end();
822 size_t nRangeSize
= rDestRanges
.size();
823 for (; itrTab
!= itrTabEnd
&& bIsEmpty
; ++itrTab
)
825 for (size_t i
= 0; i
< nRangeSize
&& bIsEmpty
; ++i
)
827 const ScRange
& rRange
= *rDestRanges
[i
];
828 bIsEmpty
= pDoc
->IsBlockEmpty(
829 *itrTab
, rRange
.aStart
.Col(), rRange
.aStart
.Row(),
830 rRange
.aEnd
.Col(), rRange
.aEnd
.Row());
836 ScopedVclPtrInstance
< ScReplaceWarnBox
> aBox(pParentWnd
);
837 if (aBox
->Execute() != RET_YES
)
839 // changing the configuration is within the ScReplaceWarnBox
848 bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags
, ScDocument
* pClipDoc
,
849 sal_uInt16 nFunction
, bool bSkipEmpty
,
850 bool bTranspose
, bool bAsLink
,
851 InsCellCmd eMoveMode
, InsertDeleteFlags nUndoExtraFlags
,
856 OSL_FAIL("PasteFromClip: pClipDoc=0 not allowed");
860 // undo: save all or no content
861 InsertDeleteFlags nContFlags
= IDF_NONE
;
862 if (nFlags
& IDF_CONTENTS
)
863 nContFlags
|= IDF_CONTENTS
;
864 if (nFlags
& IDF_ATTRIB
)
865 nContFlags
|= IDF_ATTRIB
;
866 // move attributes to undo without copying them from clip to doc
867 InsertDeleteFlags nUndoFlags
= nContFlags
;
868 if (nUndoExtraFlags
& IDF_ATTRIB
)
869 nUndoFlags
|= IDF_ATTRIB
;
870 // do not copy note captions into undo document
871 nUndoFlags
|= IDF_NOCAPTIONS
;
873 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
874 if (rClipParam
.isMultiRange())
876 // Source data is multi-range.
877 return PasteMultiRangesFromClip(
878 nFlags
, pClipDoc
, nFunction
, bSkipEmpty
, bTranspose
, bAsLink
, bAllowDialogs
,
879 eMoveMode
, nUndoFlags
);
882 ScMarkData
& rMark
= GetViewData().GetMarkData();
883 if (rMark
.IsMultiMarked())
885 // Source data is single-range but destination is multi-range.
886 return PasteFromClipToMultiRanges(
887 nFlags
, pClipDoc
, nFunction
, bSkipEmpty
, bTranspose
, bAsLink
, bAllowDialogs
,
888 eMoveMode
, nUndoFlags
);
891 bool bCutMode
= pClipDoc
->IsCutMode(); // if transposing, take from original clipdoc
892 bool bIncludeFiltered
= bCutMode
;
894 // paste drawing: also if IDF_NOTE is set (to create drawing layer for note captions)
895 bool bPasteDraw
= ( pClipDoc
->GetDrawLayer() && ( nFlags
& (IDF_OBJECTS
|IDF_NOTE
) ) );
897 ScDocShellRef aTransShellRef
; // for objects in xTransClip - must remain valid as long as xTransClip
898 ScDocument
* pOrigClipDoc
= NULL
;
899 ::std::unique_ptr
< ScDocument
> xTransClip
;
904 // include filtered rows until TransposeClip can skip them
905 bIncludeFiltered
= true;
906 pClipDoc
->GetClipArea( nX
, nY
, true );
907 if ( nY
> static_cast<sal_Int32
>(MAXCOL
) ) // to many lines for transpose
909 ErrorMessage(STR_PASTE_FULL
);
912 pOrigClipDoc
= pClipDoc
; // refs
916 aTransShellRef
= new ScDocShell
; // DocShell needs a Ref immediately
917 aTransShellRef
->DoInitNew(NULL
);
919 ScDrawLayer::SetGlobalDrawPersist(aTransShellRef
);
921 xTransClip
.reset( new ScDocument( SCDOCMODE_CLIP
));
922 pClipDoc
->TransposeClip( xTransClip
.get(), nFlags
, bAsLink
);
923 pClipDoc
= xTransClip
.get();
925 ScDrawLayer::SetGlobalDrawPersist(NULL
);
936 pClipDoc
->GetClipArea( nClipSizeX
, nClipSizeY
, true ); // size in clipboard doc
938 // size in target doc: include filtered rows only if CutMode is set
941 pClipDoc
->GetClipArea( nDestSizeX
, nDestSizeY
, bIncludeFiltered
);
943 ScDocument
* pDoc
= GetViewData().GetDocument();
944 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
945 ::svl::IUndoManager
* pUndoMgr
= pDocSh
->GetUndoManager();
946 const bool bRecord(pDoc
->IsUndoEnabled());
948 ScDocShellModificator
aModificator( *pDocSh
);
951 ScMarkData
aFilteredMark( rMark
); // local copy for all modifications
952 ScMarkType eMarkType
= GetViewData().GetSimpleArea( aMarkRange
, aFilteredMark
);
953 bool bMarkIsFiltered
= (eMarkType
== SC_MARK_SIMPLE_FILTERED
);
954 bool bNoPaste
= ((eMarkType
!= SC_MARK_SIMPLE
&& !bMarkIsFiltered
) ||
955 (bMarkIsFiltered
&& (eMoveMode
!= INS_NONE
|| bAsLink
)));
959 if (!rMark
.IsMarked())
961 // Create a selection with clipboard row count and check that for
963 nStartCol
= GetViewData().GetCurX();
964 nStartRow
= GetViewData().GetCurY();
965 nStartTab
= GetViewData().GetTabNo();
966 nEndCol
= nStartCol
+ nDestSizeX
;
967 nEndRow
= nStartRow
+ nDestSizeY
;
969 aMarkRange
= ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
970 if (ScViewUtil::HasFiltered( aMarkRange
, pDoc
))
972 bMarkIsFiltered
= true;
973 // Fit to clipboard's row count unfiltered rows. If there is no
974 // fit assume that pasting is not possible. Note that nDestSizeY is
975 // size-1 (difference).
976 if (!ScViewUtil::FitToUnfilteredRows( aMarkRange
, pDoc
, nDestSizeY
+1))
979 aFilteredMark
.SetMarkArea( aMarkRange
);
983 // Expand the marked area when the destination area is larger than the
984 // current selection, to get the undo do the right thing. (i#106711)
986 aFilteredMark
.GetMarkArea( aRange
);
987 if( (aRange
.aEnd
.Col() - aRange
.aStart
.Col()) < nDestSizeX
)
989 aRange
.aEnd
.SetCol(aRange
.aStart
.Col() + nDestSizeX
);
990 aFilteredMark
.SetMarkArea(aRange
);
997 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
1001 SCROW nUnfilteredRows
= aMarkRange
.aEnd
.Row() - aMarkRange
.aStart
.Row() + 1;
1002 ScRangeList aRangeList
;
1003 if (bMarkIsFiltered
)
1005 ScViewUtil::UnmarkFiltered( aFilteredMark
, pDoc
);
1006 aFilteredMark
.FillRangeListWithMarks( &aRangeList
, false);
1007 nUnfilteredRows
= 0;
1008 size_t ListSize
= aRangeList
.size();
1009 for ( size_t i
= 0; i
< ListSize
; ++i
)
1011 ScRange
* p
= aRangeList
[i
];
1012 nUnfilteredRows
+= p
->aEnd
.Row() - p
->aStart
.Row() + 1;
1015 /* This isn't needed but could be a desired restriction. */
1016 // For filtered, destination rows have to be an exact multiple of
1017 // source rows. Note that nDestSizeY is size-1 (difference), so
1018 // nDestSizeY==0 fits always.
1019 if ((nUnfilteredRows
% (nDestSizeY
+1)) != 0)
1021 /* FIXME: this should be a more descriptive error message then. */
1022 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
1028 // Also for a filtered selection the area is used, for undo et al.
1029 if ( aFilteredMark
.IsMarked() || bMarkIsFiltered
)
1031 aMarkRange
.GetVars( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
1032 SCCOL nBlockAddX
= nEndCol
-nStartCol
;
1033 SCROW nBlockAddY
= nEndRow
-nStartRow
;
1035 // Nachfrage, wenn die Selektion groesser als 1 Zeile/Spalte, aber kleiner
1036 // als das Clipboard ist (dann wird ueber die Selektion hinaus eingefuegt)
1038 // ClipSize is not size, but difference
1039 if ( ( nBlockAddX
!= 0 && nBlockAddX
< nDestSizeX
) ||
1040 ( nBlockAddY
!= 0 && nBlockAddY
< nDestSizeY
) ||
1041 ( bMarkIsFiltered
&& nUnfilteredRows
< nDestSizeY
+1 ) )
1043 ScWaitCursorOff
aWaitOff( GetFrameWin() );
1044 OUString aMessage
= ScGlobal::GetRscString( STR_PASTE_BIGGER
);
1045 ScopedVclPtrInstance
<QueryBox
> aBox( GetViewData().GetDialogParent(),
1046 WinBits(WB_YES_NO
| WB_DEF_NO
), aMessage
);
1047 if ( aBox
->Execute() != RET_YES
)
1053 if (nBlockAddX
<= nDestSizeX
)
1054 nEndCol
= nStartCol
+ nDestSizeX
;
1056 if (nBlockAddY
<= nDestSizeY
)
1058 nEndRow
= nStartRow
+ nDestSizeY
;
1059 if (bMarkIsFiltered
|| nEndRow
> aMarkRange
.aEnd
.Row())
1061 // Same as above if nothing was marked: re-fit selection to
1062 // unfiltered rows. Extending the selection actually may
1063 // introduce filtered rows where there weren't any before, so
1064 // we also need to test for that.
1065 aMarkRange
= ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
1066 if (bMarkIsFiltered
|| ScViewUtil::HasFiltered( aMarkRange
, pDoc
))
1068 bMarkIsFiltered
= true;
1069 // Worst case: all rows up to the end of the sheet are filtered.
1070 if (!ScViewUtil::FitToUnfilteredRows( aMarkRange
, pDoc
, nDestSizeY
+1))
1072 ErrorMessage(STR_PASTE_FULL
);
1076 aMarkRange
.GetVars( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
1077 aFilteredMark
.SetMarkArea( aMarkRange
);
1078 if (bMarkIsFiltered
)
1080 ScViewUtil::UnmarkFiltered( aFilteredMark
, pDoc
);
1081 aFilteredMark
.FillRangeListWithMarks( &aRangeList
, true);
1088 nStartCol
= GetViewData().GetCurX();
1089 nStartRow
= GetViewData().GetCurY();
1090 nStartTab
= GetViewData().GetTabNo();
1091 nEndCol
= nStartCol
+ nDestSizeX
;
1092 nEndRow
= nStartRow
+ nDestSizeY
;
1093 nEndTab
= nStartTab
;
1096 bool bOffLimits
= !ValidCol(nEndCol
) || !ValidRow(nEndRow
);
1098 // target-range, as displayed:
1099 ScRange
aUserRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
1101 // should lines be inserted?
1102 // ( too large nEndCol/nEndRow are detected below)
1103 bool bInsertCells
= ( eMoveMode
!= INS_NONE
&& !bOffLimits
);
1106 // Instead of EnterListAction, the paste undo action is merged into the
1107 // insert action, so Repeat can insert the right cells
1109 MarkRange( aUserRange
); // set through CopyFromClip
1111 // CutMode is reset on insertion of cols/rows but needed again on cell move
1112 bool bCut
= pClipDoc
->IsCutMode();
1113 if (!InsertCells( eMoveMode
, bRecord
, true )) // is inserting possible?
1116 // #i21036# EnterListAction isn't used, and InsertCells doesn't insert
1117 // its undo action on failure, so no undo handling is needed here
1120 pClipDoc
->SetCutMode( bCut
);
1122 else if (!bOffLimits
)
1124 bool bAskIfNotEmpty
= bAllowDialogs
&&
1125 ( nFlags
& IDF_CONTENTS
) &&
1126 nFunction
== PASTE_NOFUNC
&&
1127 SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1128 if ( bAskIfNotEmpty
)
1130 ScRangeList aTestRanges
;
1131 aTestRanges
.Append(aUserRange
);
1132 if (!checkDestRangeForOverwrite(aTestRanges
, pDoc
, aFilteredMark
, GetViewData().GetDialogParent()))
1137 SCCOL nClipStartX
; // enlarge clipboard-range
1139 pClipDoc
->GetClipStart( nClipStartX
, nClipStartY
);
1140 SCCOL nUndoEndCol
= nClipStartX
+ nClipSizeX
;
1141 SCROW nUndoEndRow
= nClipStartY
+ nClipSizeY
; // end of source area in clipboard document
1142 bool bClipOver
= false;
1143 // #i68690# ExtendMerge for the clip doc must be called with the clipboard's sheet numbers.
1144 // The same end column/row can be used for all calls because the clip doc doesn't contain
1145 // content outside the clip area.
1146 for (SCTAB nClipTab
=0; nClipTab
< pClipDoc
->GetTableCount(); nClipTab
++)
1147 if ( pClipDoc
->HasTable(nClipTab
) )
1148 if ( pClipDoc
->ExtendMerge( nClipStartX
,nClipStartY
, nUndoEndCol
,nUndoEndRow
, nClipTab
, false ) )
1150 nUndoEndCol
-= nClipStartX
+ nClipSizeX
;
1151 nUndoEndRow
-= nClipStartY
+ nClipSizeY
; // now contains only the difference added by ExtendMerge
1152 nUndoEndCol
= sal::static_int_cast
<SCCOL
>( nUndoEndCol
+ nEndCol
);
1153 nUndoEndRow
= sal::static_int_cast
<SCROW
>( nUndoEndRow
+ nEndRow
); // destination area, expanded for merged cells
1155 if (nUndoEndCol
>MAXCOL
|| nUndoEndRow
>MAXROW
)
1157 ErrorMessage(STR_PASTE_FULL
);
1161 pDoc
->ExtendMergeSel( nStartCol
,nStartRow
, nUndoEndCol
,nUndoEndRow
, aFilteredMark
, false );
1163 // check cell-protection
1165 ScEditableTester
aTester( pDoc
, nStartTab
, nStartCol
,nStartRow
, nUndoEndCol
,nUndoEndRow
);
1166 if (!aTester
.IsEditable())
1168 ErrorMessage(aTester
.GetMessageId());
1172 //! check overlapping
1173 //! just check truly intersection !!!!!!!
1175 ScDocFunc
& rDocFunc
= pDocSh
->GetDocFunc();
1178 OUString aUndo
= ScGlobal::GetRscString( pClipDoc
->IsCutMode() ? STR_UNDO_MOVE
: STR_UNDO_COPY
);
1179 pUndoMgr
->EnterListAction( aUndo
, aUndo
);
1183 if (lcl_SelHasAttrib( pDoc
, nStartCol
,nStartRow
, nUndoEndCol
,nUndoEndRow
, aFilteredMark
, HASATTR_OVERLAPPED
))
1184 { // "Cell merge not possible if cells already merged"
1185 ScDocAttrIterator
aIter( pDoc
, nStartTab
, nStartCol
, nStartRow
, nUndoEndCol
, nUndoEndRow
);
1186 const ScPatternAttr
* pPattern
= NULL
;
1190 while ( ( pPattern
= aIter
.GetNext( nCol
, nRow1
, nRow2
) ) != NULL
)
1192 const ScMergeAttr
* pMergeFlag
= static_cast<const ScMergeAttr
*>( &pPattern
->GetItem(ATTR_MERGE
) );
1193 const ScMergeFlagAttr
* pMergeFlagAttr
= static_cast<const ScMergeFlagAttr
*>( &pPattern
->GetItem(ATTR_MERGE_FLAG
) );
1194 if( ( pMergeFlag
&& pMergeFlag
->IsMerged() ) || ( pMergeFlagAttr
&& pMergeFlagAttr
->IsOverlapped() ) )
1196 ScRange
aRange(nCol
, nRow1
, nStartTab
);
1197 pDoc
->ExtendOverlapped(aRange
);
1198 pDoc
->ExtendMerge(aRange
, true);
1199 rDocFunc
.UnmergeCells(aRange
, bRecord
);
1206 ScChangeTrack
* pChangeTrack
= pDoc
->GetChangeTrack();
1208 pChangeTrack
->ResetLastCut(); // no more cut-mode
1211 bool bColInfo
= ( nStartRow
==0 && nEndRow
==MAXROW
);
1212 bool bRowInfo
= ( nStartCol
==0 && nEndCol
==MAXCOL
);
1214 ScDocument
* pUndoDoc
= NULL
;
1215 ScDocument
* pRefUndoDoc
= NULL
;
1216 ScRefUndoData
* pUndoData
= NULL
;
1220 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1221 pUndoDoc
->InitUndoSelected( pDoc
, aFilteredMark
, bColInfo
, bRowInfo
);
1223 // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
1224 SCTAB nTabCount
= pDoc
->GetTableCount();
1225 pDoc
->CopyToDocument( nStartCol
, nStartRow
, 0, nUndoEndCol
, nUndoEndRow
, nTabCount
-1,
1226 nUndoFlags
, false, pUndoDoc
);
1230 pRefUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1231 pRefUndoDoc
->InitUndo( pDoc
, 0, nTabCount
-1, false, false );
1233 pUndoData
= new ScRefUndoData( pDoc
);
1237 sal_uInt16 nExtFlags
= 0;
1238 pDocSh
->UpdatePaintExt( nExtFlags
, nStartCol
, nStartRow
, nStartTab
,
1239 nEndCol
, nEndRow
, nEndTab
); // content before the change
1241 if (GetViewData().IsActive())
1246 rMark
.SetMarkArea( aUserRange
);
1249 // copy from clipboard
1250 // save original data in case of calculation
1252 boost::scoped_ptr
<ScDocument
> pMixDoc
;
1256 if ( nFlags
& IDF_CONTENTS
)
1258 pMixDoc
.reset(new ScDocument( SCDOCMODE_UNDO
));
1259 pMixDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
);
1260 pDoc
->CopyToDocument( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
,
1261 IDF_CONTENTS
, false, pMixDoc
.get() );
1265 /* Make draw layer and start drawing undo.
1266 - Needed before AdjustBlockHeight to track moved drawing objects.
1267 - Needed before pDoc->CopyFromClip to track inserted note caption objects.
1270 pDocSh
->MakeDrawLayer();
1272 pDoc
->BeginDrawUndo();
1274 InsertDeleteFlags nNoObjFlags
= nFlags
& ~IDF_OBJECTS
;
1277 // copy normally (original range)
1278 pDoc
->CopyFromClip( aUserRange
, aFilteredMark
, nNoObjFlags
,
1279 pRefUndoDoc
, pClipDoc
, true, false, bIncludeFiltered
,
1280 bSkipEmpty
, (bMarkIsFiltered
? &aRangeList
: NULL
) );
1282 // adapt refs manually in case of transpose
1283 if ( bTranspose
&& bCutMode
&& (nFlags
& IDF_CONTENTS
) )
1284 pDoc
->UpdateTranspose( aUserRange
.aStart
, pOrigClipDoc
, aFilteredMark
, pRefUndoDoc
);
1286 else if (!bTranspose
)
1288 // copy with bAsLink=TRUE
1289 pDoc
->CopyFromClip( aUserRange
, aFilteredMark
, nNoObjFlags
, pRefUndoDoc
, pClipDoc
,
1290 true, true, bIncludeFiltered
, bSkipEmpty
);
1294 // copy all content (TransClipDoc contains only formula)
1295 pDoc
->CopyFromClip( aUserRange
, aFilteredMark
, nContFlags
, pRefUndoDoc
, pClipDoc
);
1298 // skipped rows and merged cells don't mix
1299 if ( !bIncludeFiltered
&& pClipDoc
->HasClipFilteredRows() )
1300 rDocFunc
.UnmergeCells( aUserRange
, false );
1302 pDoc
->ExtendMergeSel( nStartCol
, nStartRow
, nEndCol
, nEndRow
, aFilteredMark
, true ); // refresh
1305 if ( pMixDoc
) // calculate with originial data ?
1307 pDoc
->MixDocument( aUserRange
, nFunction
, bSkipEmpty
, pMixDoc
.get() );
1311 AdjustBlockHeight(); // update row heights before pasting objects
1313 ::std::vector
< OUString
> aExcludedChartNames
;
1314 SdrPage
* pPage
= NULL
;
1316 if ( nFlags
& IDF_OBJECTS
)
1318 ScDrawView
* pScDrawView
= GetScDrawView();
1319 SdrModel
* pModel
= ( pScDrawView
? pScDrawView
->GetModel() : NULL
);
1320 pPage
= ( pModel
? pModel
->GetPage( static_cast< sal_uInt16
>( nStartTab
) ) : NULL
);
1323 ScChartHelper::GetChartNames( aExcludedChartNames
, pPage
);
1326 // Paste the drawing objects after the row heights have been updated.
1328 pDoc
->CopyFromClip( aUserRange
, aFilteredMark
, IDF_OBJECTS
, pRefUndoDoc
, pClipDoc
,
1329 true, false, bIncludeFiltered
);
1332 pDocSh
->UpdatePaintExt( nExtFlags
, nStartCol
, nStartRow
, nStartTab
,
1333 nEndCol
, nEndRow
, nEndTab
); // content after the change
1335 // if necessary, delete autofilter-heads
1337 if (pDoc
->RefreshAutoFilter( nClipStartX
,nClipStartY
, nClipStartX
+nClipSizeX
,
1338 nClipStartY
+nClipSizeY
, nStartTab
))
1341 ScRange(nClipStartX
, nClipStartY
, nStartTab
, nClipStartX
+nClipSizeX
, nClipStartY
, nStartTab
),
1345 //! remove block-range on RefUndoDoc !!!
1349 ScDocument
* pRedoDoc
= NULL
;
1350 // copy redo data after appearance of the first undo
1351 // don't create Redo-Doc without RefUndoDoc
1355 pRedoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1356 pRedoDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
, bColInfo
, bRowInfo
);
1358 // move adapted refs to Redo-Doc
1360 SCTAB nTabCount
= pDoc
->GetTableCount();
1361 pRedoDoc
->AddUndoTab( 0, nTabCount
-1 );
1362 pDoc
->CopyUpdated( pRefUndoDoc
, pRedoDoc
);
1364 // move old refs to Undo-Doc
1367 pUndoDoc
->AddUndoTab( 0, nTabCount
-1 );
1368 pRefUndoDoc
->DeleteArea( nStartCol
, nStartRow
, nEndCol
, nEndRow
, aFilteredMark
, IDF_ALL
);
1369 pRefUndoDoc
->CopyToDocument( 0,0,0, MAXCOL
,MAXROW
,nTabCount
-1,
1370 IDF_FORMULA
, false, pUndoDoc
);
1374 // DeleteUnchanged for pUndoData is in ScUndoPaste ctor,
1375 // UndoData for redo is made during first undo
1377 ScUndoPasteOptions aOptions
; // store options for repeat
1378 aOptions
.nFunction
= nFunction
;
1379 aOptions
.bSkipEmpty
= bSkipEmpty
;
1380 aOptions
.bTranspose
= bTranspose
;
1381 aOptions
.bAsLink
= bAsLink
;
1382 aOptions
.eMoveMode
= eMoveMode
;
1384 SfxUndoAction
* pUndo
= new ScUndoPaste(
1385 pDocSh
, ScRange(nStartCol
, nStartRow
, nStartTab
, nUndoEndCol
, nUndoEndRow
, nEndTab
),
1386 aFilteredMark
, pUndoDoc
, pRedoDoc
, nFlags
| nUndoFlags
, pUndoData
,
1387 false, &aOptions
); // false = Redo data not yet copied
1391 // Merge the paste undo action into the insert action.
1392 // Use ScUndoWrapper so the ScUndoPaste pointer can be stored in the insert action.
1394 pUndoMgr
->AddUndoAction( new ScUndoWrapper( pUndo
), true );
1397 pUndoMgr
->AddUndoAction( pUndo
);
1398 pUndoMgr
->LeaveListAction();
1401 sal_uInt16 nPaint
= PAINT_GRID
;
1404 nPaint
|= PAINT_TOP
;
1405 nUndoEndCol
= MAXCOL
; // just for drawing !
1409 nPaint
|= PAINT_LEFT
;
1410 nUndoEndRow
= MAXROW
; // just for drawing !
1413 ScRange(nStartCol
, nStartRow
, nStartTab
, nUndoEndCol
, nUndoEndRow
, nEndTab
),
1415 // AdjustBlockHeight has already been called above
1418 aModificator
.SetDocumentModified();
1419 PostPasteFromClip(aUserRange
, rMark
);
1421 if ( nFlags
& IDF_OBJECTS
)
1423 ScModelObj
* pModelObj
= ScModelObj::getImplementation( pDocSh
->GetModel() );
1424 if ( pPage
&& pModelObj
)
1426 bool bSameDoc
= ( rClipParam
.getSourceDocID() == pDoc
->GetDocumentID() );
1427 const ScRangeListVector
& rProtectedChartRangesVector( rClipParam
.maProtectedChartRangesVector
);
1428 ScChartHelper::CreateProtectedChartListenersAndNotify( pDoc
, pPage
, pModelObj
, nStartTab
,
1429 rProtectedChartRangesVector
, aExcludedChartNames
, bSameDoc
);
1436 bool ScViewFunc::PasteMultiRangesFromClip(
1437 InsertDeleteFlags nFlags
, ScDocument
* pClipDoc
, sal_uInt16 nFunction
,
1438 bool bSkipEmpty
, bool bTranspose
, bool bAsLink
, bool bAllowDialogs
,
1439 InsCellCmd eMoveMode
, InsertDeleteFlags nUndoFlags
)
1441 ScViewData
& rViewData
= GetViewData();
1442 ScDocument
* pDoc
= rViewData
.GetDocument();
1443 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
1444 ScMarkData
aMark(rViewData
.GetMarkData());
1445 const ScAddress
& rCurPos
= rViewData
.GetCurPos();
1446 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
1447 SCCOL nColSize
= rClipParam
.getPasteColSize();
1448 SCROW nRowSize
= rClipParam
.getPasteRowSize();
1452 if (static_cast<SCROW
>(rCurPos
.Col()) + nRowSize
-1 > static_cast<SCROW
>(MAXCOL
))
1454 ErrorMessage(STR_PASTE_FULL
);
1458 ::std::unique_ptr
<ScDocument
> pTransClip(new ScDocument(SCDOCMODE_CLIP
));
1459 pClipDoc
->TransposeClip(pTransClip
.get(), nFlags
, bAsLink
);
1460 pClipDoc
= pTransClip
.release();
1461 SCCOL nTempColSize
= nColSize
;
1462 nColSize
= static_cast<SCCOL
>(nRowSize
);
1463 nRowSize
= static_cast<SCROW
>(nTempColSize
);
1466 if (!ValidCol(rCurPos
.Col()+nColSize
-1) || !ValidRow(rCurPos
.Row()+nRowSize
-1))
1468 ErrorMessage(STR_PASTE_FULL
);
1472 // Determine the first and last selected sheet numbers.
1473 SCTAB nTab1
= aMark
.GetFirstSelected();
1474 SCTAB nTab2
= aMark
.GetLastSelected();
1476 ScDocShellModificator
aModificator(*pDocSh
);
1478 // For multi-selection paste, we don't support cell duplication for larger
1479 // destination range. In case the destination is marked, we reset it to
1481 ScRange
aMarkedRange(rCurPos
.Col(), rCurPos
.Row(), nTab1
,
1482 rCurPos
.Col()+nColSize
-1, rCurPos
.Row()+nRowSize
-1, nTab2
);
1484 // Extend the marked range to account for filtered rows in the destination
1486 if (ScViewUtil::HasFiltered(aMarkedRange
, pDoc
))
1488 if (!ScViewUtil::FitToUnfilteredRows(aMarkedRange
, pDoc
, nRowSize
))
1492 bool bAskIfNotEmpty
=
1493 bAllowDialogs
&& (nFlags
& IDF_CONTENTS
) &&
1494 nFunction
== PASTE_NOFUNC
&& SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1498 ScRangeList aTestRanges
;
1499 aTestRanges
.Append(aMarkedRange
);
1500 if (!checkDestRangeForOverwrite(aTestRanges
, pDoc
, aMark
, rViewData
.GetDialogParent()))
1504 aMark
.SetMarkArea(aMarkedRange
);
1505 MarkRange(aMarkedRange
);
1507 bool bInsertCells
= (eMoveMode
!= INS_NONE
);
1510 if (!InsertCells(eMoveMode
, pDoc
->IsUndoEnabled(), true))
1514 ::std::unique_ptr
<ScDocument
> pUndoDoc
;
1515 if (pDoc
->IsUndoEnabled())
1517 pUndoDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
1518 pUndoDoc
->InitUndoSelected(pDoc
, aMark
, false, false);
1519 pDoc
->CopyToDocument(aMarkedRange
, nUndoFlags
, false, pUndoDoc
.get(), &aMark
, true);
1522 ::std::unique_ptr
<ScDocument
> pMixDoc
;
1523 if ( bSkipEmpty
|| nFunction
)
1525 if ( nFlags
& IDF_CONTENTS
)
1527 pMixDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
1528 pMixDoc
->InitUndoSelected(pDoc
, aMark
, false, false);
1529 pDoc
->CopyToDocument(aMarkedRange
, IDF_CONTENTS
, false, pMixDoc
.get(), &aMark
, true);
1533 /* Make draw layer and start drawing undo.
1534 - Needed before AdjustBlockHeight to track moved drawing objects.
1535 - Needed before pDoc->CopyFromClip to track inserted note caption objects.
1537 if (nFlags
& IDF_OBJECTS
)
1538 pDocSh
->MakeDrawLayer();
1539 if (pDoc
->IsUndoEnabled())
1540 pDoc
->BeginDrawUndo();
1542 InsertDeleteFlags nNoObjFlags
= nFlags
& ~IDF_OBJECTS
;
1543 pDoc
->CopyMultiRangeFromClip(rCurPos
, aMark
, nNoObjFlags
, pClipDoc
,
1544 true, bAsLink
, false, bSkipEmpty
);
1547 pDoc
->MixDocument(aMarkedRange
, nFunction
, bSkipEmpty
, pMixDoc
.get());
1549 AdjustBlockHeight(); // update row heights before pasting objects
1551 if (nFlags
& IDF_OBJECTS
)
1553 // Paste the drawing objects after the row heights have been updated.
1554 pDoc
->CopyMultiRangeFromClip(rCurPos
, aMark
, IDF_OBJECTS
, pClipDoc
,
1555 true, false, false, true);
1558 ScRange aTmp
= aMarkedRange
;
1559 aTmp
.aStart
.SetTab(nTab1
);
1560 aTmp
.aEnd
.SetTab(nTab1
);
1561 pDocSh
->PostPaint(aTmp
, PAINT_GRID
);
1563 if (pDoc
->IsUndoEnabled())
1565 ::svl::IUndoManager
* pUndoMgr
= pDocSh
->GetUndoManager();
1566 OUString aUndo
= ScGlobal::GetRscString(
1567 pClipDoc
->IsCutMode() ? STR_UNDO_CUT
: STR_UNDO_COPY
);
1568 pUndoMgr
->EnterListAction(aUndo
, aUndo
);
1570 ScUndoPasteOptions aOptions
; // store options for repeat
1571 aOptions
.nFunction
= nFunction
;
1572 aOptions
.bSkipEmpty
= bSkipEmpty
;
1573 aOptions
.bTranspose
= bTranspose
;
1574 aOptions
.bAsLink
= bAsLink
;
1575 aOptions
.eMoveMode
= eMoveMode
;
1577 ScUndoPaste
* pUndo
= new ScUndoPaste(pDocSh
,
1578 aMarkedRange
, aMark
, pUndoDoc
.release(), NULL
, nFlags
|nUndoFlags
, NULL
, false, &aOptions
);
1581 pUndoMgr
->AddUndoAction(new ScUndoWrapper(pUndo
), true);
1583 pUndoMgr
->AddUndoAction(pUndo
, false);
1585 pUndoMgr
->LeaveListAction();
1589 aModificator
.SetDocumentModified();
1590 PostPasteFromClip(aMarkedRange
, aMark
);
1594 bool ScViewFunc::PasteFromClipToMultiRanges(
1595 InsertDeleteFlags nFlags
, ScDocument
* pClipDoc
, sal_uInt16 nFunction
,
1596 bool bSkipEmpty
, bool bTranspose
, bool bAsLink
, bool bAllowDialogs
,
1597 InsCellCmd eMoveMode
, InsertDeleteFlags nUndoFlags
)
1601 // We don't allow transpose for this yet.
1602 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
1606 if (eMoveMode
!= INS_NONE
)
1608 // We don't allow insertion mode either. Too complicated.
1609 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
1613 ScViewData
& rViewData
= GetViewData();
1614 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
1615 if (rClipParam
.mbCutMode
)
1617 // No cut and paste with this, please.
1618 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
1622 const ScAddress
& rCurPos
= rViewData
.GetCurPos();
1623 ScDocument
* pDoc
= rViewData
.GetDocument();
1625 ScRange aSrcRange
= rClipParam
.getWholeRange();
1626 SCROW nRowSize
= aSrcRange
.aEnd
.Row() - aSrcRange
.aStart
.Row() + 1;
1627 SCCOL nColSize
= aSrcRange
.aEnd
.Col() - aSrcRange
.aStart
.Col() + 1;
1629 if (!ValidCol(rCurPos
.Col()+nColSize
-1) || !ValidRow(rCurPos
.Row()+nRowSize
-1))
1631 ErrorMessage(STR_PASTE_FULL
);
1635 ScMarkData
aMark(rViewData
.GetMarkData());
1637 ScRangeList aRanges
;
1638 aMark
.MarkToSimple();
1639 aMark
.FillRangeListWithMarks(&aRanges
, false);
1640 if (!ScClipUtil::CheckDestRanges(pDoc
, nColSize
, nRowSize
, aMark
, aRanges
))
1642 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
1646 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
1648 ScDocShellModificator
aModificator(*pDocSh
);
1650 bool bAskIfNotEmpty
=
1651 bAllowDialogs
&& (nFlags
& IDF_CONTENTS
) &&
1652 nFunction
== PASTE_NOFUNC
&& SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1656 if (!checkDestRangeForOverwrite(aRanges
, pDoc
, aMark
, rViewData
.GetDialogParent()))
1660 std::unique_ptr
<ScDocument
> pUndoDoc
;
1661 if (pDoc
->IsUndoEnabled())
1663 pUndoDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
1664 pUndoDoc
->InitUndoSelected(pDoc
, aMark
, false, false);
1665 for (size_t i
= 0, n
= aRanges
.size(); i
< n
; ++i
)
1667 pDoc
->CopyToDocument(
1668 *aRanges
[i
], nUndoFlags
, false, pUndoDoc
.get(), &aMark
, true);
1672 boost::scoped_ptr
<ScDocument
> pMixDoc
;
1673 if (bSkipEmpty
|| nFunction
)
1675 if (nFlags
& IDF_CONTENTS
)
1677 pMixDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
1678 pMixDoc
->InitUndoSelected(pDoc
, aMark
, false, false);
1679 for (size_t i
= 0, n
= aRanges
.size(); i
< n
; ++i
)
1681 pDoc
->CopyToDocument(
1682 *aRanges
[i
], IDF_CONTENTS
, false, pMixDoc
.get(), &aMark
, true);
1687 if (nFlags
& IDF_OBJECTS
)
1688 pDocSh
->MakeDrawLayer();
1689 if (pDoc
->IsUndoEnabled())
1690 pDoc
->BeginDrawUndo();
1692 // First, paste everything but the drawing objects.
1693 for (size_t i
= 0, n
= aRanges
.size(); i
< n
; ++i
)
1696 *aRanges
[i
], aMark
, (nFlags
& ~IDF_OBJECTS
), NULL
, pClipDoc
,
1697 false, false, true, bSkipEmpty
, NULL
);
1702 for (size_t i
= 0, n
= aRanges
.size(); i
< n
; ++i
)
1703 pDoc
->MixDocument(*aRanges
[i
], nFunction
, bSkipEmpty
, pMixDoc
.get());
1706 AdjustBlockHeight(); // update row heights before pasting objects
1708 // Then paste the objects.
1709 if (nFlags
& IDF_OBJECTS
)
1711 for (size_t i
= 0, n
= aRanges
.size(); i
< n
; ++i
)
1714 *aRanges
[i
], aMark
, IDF_OBJECTS
, NULL
, pClipDoc
,
1715 false, false, true, bSkipEmpty
, NULL
);
1719 // Refresh the range that includes all pasted ranges. We only need to
1720 // refresh the current sheet.
1721 pDocSh
->PostPaint(aRanges
, PAINT_GRID
);
1723 if (pDoc
->IsUndoEnabled())
1725 svl::IUndoManager
* pUndoMgr
= pDocSh
->GetUndoManager();
1726 OUString aUndo
= ScGlobal::GetRscString(
1727 pClipDoc
->IsCutMode() ? STR_UNDO_CUT
: STR_UNDO_COPY
);
1728 pUndoMgr
->EnterListAction(aUndo
, aUndo
);
1730 ScUndoPasteOptions aOptions
; // store options for repeat
1731 aOptions
.nFunction
= nFunction
;
1732 aOptions
.bSkipEmpty
= bSkipEmpty
;
1733 aOptions
.bTranspose
= bTranspose
;
1734 aOptions
.bAsLink
= bAsLink
;
1735 aOptions
.eMoveMode
= eMoveMode
;
1737 ScUndoPaste
* pUndo
= new ScUndoPaste(
1738 pDocSh
, aRanges
, aMark
, pUndoDoc
.release(), NULL
, nFlags
|nUndoFlags
, NULL
, false, &aOptions
);
1740 pUndoMgr
->AddUndoAction(pUndo
, false);
1741 pUndoMgr
->LeaveListAction();
1745 aModificator
.SetDocumentModified();
1746 PostPasteFromClip(aRanges
, aMark
);
1751 void ScViewFunc::PostPasteFromClip(const ScRangeList
& rPasteRanges
, const ScMarkData
& rMark
)
1753 ScViewData
& rViewData
= GetViewData();
1754 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
1755 pDocSh
->UpdateOle(&rViewData
);
1759 ScModelObj
* pModelObj
= HelperNotifyChanges::getMustPropagateChangesModel(*pDocSh
);
1763 ScRangeList aChangeRanges
;
1764 for (size_t i
= 0, n
= rPasteRanges
.size(); i
< n
; ++i
)
1766 const ScRange
& r
= *rPasteRanges
[i
];
1767 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1768 for (; itr
!= itrEnd
; ++itr
)
1770 ScRange
aChangeRange(r
);
1771 aChangeRange
.aStart
.SetTab(*itr
);
1772 aChangeRange
.aEnd
.SetTab(*itr
);
1773 aChangeRanges
.Append(aChangeRange
);
1776 HelperNotifyChanges::Notify(*pModelObj
, aChangeRanges
);
1779 // D R A G A N D D R O P
1783 bool ScViewFunc::MoveBlockTo( const ScRange
& rSource
, const ScAddress
& rDestPos
,
1784 bool bCut
, bool bRecord
, bool bPaint
, bool bApi
)
1786 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1789 bool bSuccess
= true;
1790 SCTAB nDestTab
= rDestPos
.Tab();
1791 const ScMarkData
& rMark
= GetViewData().GetMarkData();
1792 if ( rSource
.aStart
.Tab() == nDestTab
&& rSource
.aEnd
.Tab() == nDestTab
&& rMark
.GetSelectCount() > 1 )
1794 // moving within one table and several tables selected -> apply to all selected tables
1798 OUString aUndo
= ScGlobal::GetRscString( bCut
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
1799 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
1802 // collect ranges of consecutive selected tables
1804 ScRange aLocalSource
= rSource
;
1805 ScAddress aLocalDest
= rDestPos
;
1806 SCTAB nTabCount
= pDocSh
->GetDocument().GetTableCount();
1807 SCTAB nStartTab
= 0;
1808 while ( nStartTab
< nTabCount
&& bSuccess
)
1810 while ( nStartTab
< nTabCount
&& !rMark
.GetTableSelect(nStartTab
) )
1812 if ( nStartTab
< nTabCount
)
1814 SCTAB nEndTab
= nStartTab
;
1815 while ( nEndTab
+1 < nTabCount
&& rMark
.GetTableSelect(nEndTab
+1) )
1818 aLocalSource
.aStart
.SetTab( nStartTab
);
1819 aLocalSource
.aEnd
.SetTab( nEndTab
);
1820 aLocalDest
.SetTab( nStartTab
);
1822 bSuccess
= pDocSh
->GetDocFunc().MoveBlock(
1823 aLocalSource
, aLocalDest
, bCut
, bRecord
, bPaint
, bApi
);
1825 nStartTab
= nEndTab
+ 1;
1830 pDocSh
->GetUndoManager()->LeaveListAction();
1834 // move the block as specified
1835 bSuccess
= pDocSh
->GetDocFunc().MoveBlock(
1836 rSource
, rDestPos
, bCut
, bRecord
, bPaint
, bApi
);
1842 // mark destination range
1844 rDestPos
.Col() + rSource
.aEnd
.Col() - rSource
.aStart
.Col(),
1845 rDestPos
.Row() + rSource
.aEnd
.Row() - rSource
.aStart
.Row(),
1848 bool bIncludeFiltered
= bCut
;
1849 if ( !bIncludeFiltered
)
1851 // find number of non-filtered rows
1852 SCROW nPastedCount
= pDocSh
->GetDocument().CountNonFilteredRows(
1853 rSource
.aStart
.Row(), rSource
.aEnd
.Row(), rSource
.aStart
.Tab());
1855 if ( nPastedCount
== 0 )
1857 aDestEnd
.SetRow( rDestPos
.Row() + nPastedCount
- 1 );
1860 MarkRange( ScRange( rDestPos
, aDestEnd
), false ); //! sal_False ???
1862 pDocSh
->UpdateOle(&GetViewData());
1869 // link inside the doc
1871 bool ScViewFunc::LinkBlock( const ScRange
& rSource
, const ScAddress
& rDestPos
, bool bApi
)
1873 // check overlapping
1875 if ( rSource
.aStart
.Tab() == rDestPos
.Tab() )
1877 SCCOL nDestEndCol
= rDestPos
.Col() + ( rSource
.aEnd
.Col() - rSource
.aStart
.Col() );
1878 SCROW nDestEndRow
= rDestPos
.Row() + ( rSource
.aEnd
.Row() - rSource
.aStart
.Row() );
1880 if ( rSource
.aStart
.Col() <= nDestEndCol
&& rDestPos
.Col() <= rSource
.aEnd
.Col() &&
1881 rSource
.aStart
.Row() <= nDestEndRow
&& rDestPos
.Row() <= rSource
.aEnd
.Row() )
1884 ErrorMessage( STR_ERR_LINKOVERLAP
);
1891 ScDocument
* pDoc
= GetViewData().GetDocument();
1892 boost::scoped_ptr
<ScDocument
> pClipDoc(new ScDocument( SCDOCMODE_CLIP
));
1893 pDoc
->CopyTabToClip( rSource
.aStart
.Col(), rSource
.aStart
.Row(),
1894 rSource
.aEnd
.Col(), rSource
.aEnd
.Row(),
1895 rSource
.aStart
.Tab(), pClipDoc
.get() );
1897 // mark destination area (set cursor, no marks)
1899 if ( GetViewData().GetTabNo() != rDestPos
.Tab() )
1900 SetTabNo( rDestPos
.Tab() );
1902 MoveCursorAbs( rDestPos
.Col(), rDestPos
.Row(), SC_FOLLOW_NONE
, false, false );
1906 PasteFromClip( IDF_ALL
, pClipDoc
.get(), PASTE_NOFUNC
, false, false, true ); // as a link
1911 void ScViewFunc::DataFormPutData( SCROW nCurrentRow
,
1912 SCROW nStartRow
, SCCOL nStartCol
,
1913 SCROW nEndRow
, SCCOL nEndCol
,
1914 std::vector
<VclPtr
<Edit
> >& aEdits
,
1915 sal_uInt16 aColLength
)
1917 ScDocument
* pDoc
= GetViewData().GetDocument();
1918 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1919 ScMarkData
& rMark
= GetViewData().GetMarkData();
1920 ScDocShellModificator
aModificator( *pDocSh
);
1921 ::svl::IUndoManager
* pUndoMgr
= pDocSh
->GetUndoManager();
1924 const bool bRecord( pDoc
->IsUndoEnabled());
1925 ScDocument
* pUndoDoc
= NULL
;
1926 ScDocument
* pRedoDoc
= NULL
;
1927 ScRefUndoData
* pUndoData
= NULL
;
1928 SCTAB nTab
= GetViewData().GetTabNo();
1929 SCTAB nStartTab
= nTab
;
1930 SCTAB nEndTab
= nTab
;
1933 ScChangeTrack
* pChangeTrack
= pDoc
->GetChangeTrack();
1935 pChangeTrack
->ResetLastCut(); // no more cut-mode
1937 ScRange
aUserRange( nStartCol
, nCurrentRow
, nStartTab
, nEndCol
, nCurrentRow
, nEndTab
);
1938 bool bColInfo
= ( nStartRow
==0 && nEndRow
==MAXROW
);
1939 bool bRowInfo
= ( nStartCol
==0 && nEndCol
==MAXCOL
);
1940 SCCOL nUndoEndCol
= nStartCol
+aColLength
-1;
1941 SCROW nUndoEndRow
= nCurrentRow
;
1942 InsertDeleteFlags nUndoFlags
= IDF_NONE
;
1946 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1947 pUndoDoc
->InitUndoSelected( pDoc
, rMark
, bColInfo
, bRowInfo
);
1948 pDoc
->CopyToDocument( aUserRange
, IDF_VALUE
, false , pUndoDoc
);
1950 sal_uInt16 nExtFlags
= 0;
1951 pDocSh
->UpdatePaintExt( nExtFlags
, nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
); // content before the change
1952 pDoc
->BeginDrawUndo();
1954 for(sal_uInt16 i
= 0; i
< aColLength
; i
++)
1956 if (aEdits
[i
] != nullptr)
1958 OUString aFieldName
=aEdits
[i
]->GetText();
1959 pDoc
->SetString( nStartCol
+ i
, nCurrentRow
, nTab
, aFieldName
);
1962 pDocSh
->UpdatePaintExt( nExtFlags
, nStartCol
, nCurrentRow
, nStartTab
, nEndCol
, nCurrentRow
, nEndTab
); // content after the change
1963 SfxUndoAction
* pUndo
= new ScUndoDataForm( pDocSh
,
1964 nStartCol
, nCurrentRow
, nStartTab
,
1965 nUndoEndCol
, nUndoEndRow
, nEndTab
, rMark
,
1966 pUndoDoc
, pRedoDoc
, nUndoFlags
,
1967 pUndoData
, NULL
, NULL
, NULL
,
1968 false ); // FALSE = Redo data not yet copied
1969 pUndoMgr
->AddUndoAction( new ScUndoWrapper( pUndo
), true );
1971 sal_uInt16 nPaint
= PAINT_GRID
;
1974 nPaint
|= PAINT_TOP
;
1975 nUndoEndCol
= MAXCOL
; // just for drawing !
1979 nPaint
|= PAINT_LEFT
;
1980 nUndoEndRow
= MAXROW
; // just for drawing !
1984 ScRange(nStartCol
, nCurrentRow
, nStartTab
, nUndoEndCol
, nUndoEndRow
, nEndTab
),
1986 pDocSh
->UpdateOle(&GetViewData());
1990 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */