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 <vcl/graph.hxx>
33 #include <vcl/virdev.hxx>
34 #include <vcl/msgbox.hxx>
35 #include <tools/urlobj.hxx>
36 #include <sot/exchange.hxx>
40 #include "patattr.hxx"
41 #include "dociter.hxx"
42 #include "viewfunc.hxx"
43 #include "tabvwsh.hxx"
45 #include "docfunc.hxx"
46 #include "undoblk.hxx"
47 #include "refundo.hxx"
48 #include "globstr.hrc"
50 #include "transobj.hxx"
51 #include "drwtrans.hxx"
52 #include "rangenam.hxx"
55 #include "chgtrack.hxx"
56 #include "waitoff.hxx"
59 #include "inputopt.hxx"
60 #include "warnbox.hxx"
61 #include "drwlayer.hxx"
62 #include "editable.hxx"
64 #include "clipparam.hxx"
65 #include "undodat.hxx"
66 #include "drawview.hxx"
67 #include "cliputil.hxx"
68 #include <gridwin.hxx>
69 #include <boost/scoped_ptr.hpp>
71 using namespace com::sun::star
;
73 // STATIC DATA ---------------------------------------------------------------
76 // GlobalName der Writer-DocShell kommt jetzt aus comphelper/classids.hxx
81 void ScViewFunc::CutToClip( ScDocument
* pClipDoc
, bool bIncludeObjects
)
85 ScEditableTester
aTester( this );
86 if (!aTester
.IsEditable()) // selection editable?
88 ErrorMessage( aTester
.GetMessageId() );
92 ScRange aRange
; // zu loeschender Bereich
93 if ( GetViewData()->GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
95 ScDocument
* pDoc
= GetViewData()->GetDocument();
96 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
97 ScMarkData
& rMark
= GetViewData()->GetMarkData();
98 const bool bRecord(pDoc
->IsUndoEnabled()); // Undo/Redo
100 ScDocShellModificator
aModificator( *pDocSh
);
102 if ( !rMark
.IsMarked() && !rMark
.IsMultiMarked() ) // mark the range if not marked yet
106 rMark
.SetMarkArea( aRange
);
110 CopyToClip( pClipDoc
, true, false, bIncludeObjects
); // Ab ins Clipboard
112 ScAddress
aOldEnd( aRange
.aEnd
); // Zusammengefasste Zellen im Bereich?
113 pDoc
->ExtendMerge( aRange
, true );
115 ScDocument
* pUndoDoc
= NULL
;
118 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
119 pUndoDoc
->InitUndoSelected( pDoc
, rMark
);
120 // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
121 ScRange aCopyRange
= aRange
;
122 aCopyRange
.aStart
.SetTab(0);
123 aCopyRange
.aEnd
.SetTab(pDoc
->GetTableCount()-1);
124 pDoc
->CopyToDocument( aCopyRange
, (IDF_ALL
& ~IDF_OBJECTS
) | IDF_NOCAPTIONS
, false, pUndoDoc
);
125 pDoc
->BeginDrawUndo();
128 sal_uInt16 nExtFlags
= 0;
129 pDocSh
->UpdatePaintExt( nExtFlags
, aRange
);
132 pDoc
->DeleteSelection( IDF_ALL
, rMark
);
133 if ( bIncludeObjects
)
134 pDoc
->DeleteObjectsInSelection( rMark
);
135 rMark
.MarkToSimple();
137 if ( !AdjustRowHeight( aRange
.aStart
.Row(), aRange
.aEnd
.Row() ) )
138 pDocSh
->PostPaint( aRange
, PAINT_GRID
, nExtFlags
);
140 if ( bRecord
) // erst jetzt ist Draw-Undo verfuegbar
141 pDocSh
->GetUndoManager()->AddUndoAction(
142 new ScUndoCut( pDocSh
, aRange
, aOldEnd
, rMark
, pUndoDoc
) );
144 aModificator
.SetDocumentModified();
145 pDocSh
->UpdateOle(GetViewData());
147 CellContentChanged();
150 ErrorMessage( STR_NOMULTISELECT
);
155 bool ScViewFunc::CopyToClip( ScDocument
* pClipDoc
, bool bCut
, bool bApi
, bool bIncludeObjects
, bool bStopEdit
)
158 ScMarkType eMarkType
= GetViewData()->GetSimpleArea( aRange
);
159 ScMarkData
& rMark
= GetViewData()->GetMarkData();
162 if ( eMarkType
== SC_MARK_SIMPLE
|| eMarkType
== SC_MARK_SIMPLE_FILTERED
)
164 ScRangeList aRangeList
;
165 aRangeList
.Append( aRange
);
166 bDone
= CopyToClip( pClipDoc
, aRangeList
, bCut
, bApi
, bIncludeObjects
, bStopEdit
, false );
168 else if (eMarkType
== SC_MARK_MULTI
)
170 ScRangeList aRangeList
;
171 rMark
.MarkToSimple();
172 rMark
.FillRangeListWithMarks(&aRangeList
, false);
173 bDone
= CopyToClip( pClipDoc
, aRangeList
, bCut
, bApi
, bIncludeObjects
, bStopEdit
, false );
178 ErrorMessage(STR_NOMULTISELECT
);
184 // Copy the content of the Range into clipboard.
185 bool ScViewFunc::CopyToClip( ScDocument
* pClipDoc
, const ScRangeList
& rRanges
, bool bCut
, bool bApi
, bool bIncludeObjects
, bool bStopEdit
, bool bUseRangeForVBA
)
187 if ( rRanges
.empty() )
193 ScRange aRange
= *rRanges
[0];
194 ScClipParam
aClipParam( aRange
, bCut
);
195 aClipParam
.maRanges
= rRanges
;
197 ScDocument
* pDoc
= GetViewData()->GetDocument();
198 ScMarkData
& rMark
= GetViewData()->GetMarkData();
200 if ( !aClipParam
.isMultiRange() )
202 if ( pDoc
&& ( !pDoc
->HasSelectedBlockMatrixFragment( aRange
.aStart
.Col(), aRange
.aStart
.Row(), aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), rMark
) ) )
204 bool bSysClip
= false;
205 if ( !pClipDoc
) // no clip doc specified
207 // Create one (deleted by ScTransferObj).
208 pClipDoc
= new ScDocument( SCDOCMODE_CLIP
);
209 bSysClip
= true; // and copy into system
213 ScChangeTrack
* pChangeTrack
= pDoc
->GetChangeTrack();
215 pChangeTrack
->ResetLastCut();
218 if ( bSysClip
&& bIncludeObjects
)
220 bool bAnyOle
= pDoc
->HasOLEObjectsInArea( aRange
);
221 // Update ScGlobal::pDrawClipDocShellRef.
222 ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle
) );
225 if ( !bUseRangeForVBA
)
226 // is this necessary?, will setting the doc id upset the
227 // following paste operation with range? would be nicer to just set this always
228 // and lose the 'if' above
229 aClipParam
.setSourceDocID( pDoc
->GetDocumentID() );
231 pDoc
->CopyToClip( aClipParam
, pClipDoc
, &rMark
, false, false, bIncludeObjects
, true, bUseRangeForVBA
);
232 if ( !bUseRangeForVBA
&& pDoc
&& pClipDoc
)
234 ScDrawLayer
* pDrawLayer
= pClipDoc
->GetDrawLayer();
237 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
238 ScRangeListVector
& rRangesVector
= rClipParam
.maProtectedChartRangesVector
;
239 SCTAB nTabCount
= pClipDoc
->GetTableCount();
240 for ( SCTAB nTab
= 0; nTab
< nTabCount
; ++nTab
)
242 SdrPage
* pPage
= pDrawLayer
->GetPage( static_cast< sal_uInt16
>( nTab
) );
245 ScChartHelper::FillProtectedChartRangesVector( rRangesVector
, pDoc
, pPage
);
253 ScDrawLayer::SetGlobalDrawPersist(NULL
);
254 ScGlobal::SetClipDocName( pDoc
->GetDocumentShell()->GetTitle( SFX_TITLE_FULLNAME
) );
256 pClipDoc
->ExtendMerge( aRange
, true );
260 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
261 TransferableObjectDescriptor aObjDesc
;
262 pDocSh
->FillTransferableObjectDescriptor( aObjDesc
);
263 aObjDesc
.maDisplayName
= pDocSh
->GetMedium()->GetURLObject().GetURLNoPass();
264 // maSize is set in ScTransferObj ctor
266 ScTransferObj
* pTransferObj
= new ScTransferObj( pClipDoc
, aObjDesc
);
267 uno::Reference
<datatransfer::XTransferable
> xTransferable( pTransferObj
);
268 if ( ScGlobal::pDrawClipDocShellRef
)
270 SfxObjectShellRef
aPersistRef( &(*ScGlobal::pDrawClipDocShellRef
) );
271 pTransferObj
->SetDrawPersist( aPersistRef
);// keep persist for ole objects alive
274 pTransferObj
->CopyToClipboard( GetActiveWin() );
275 SC_MOD()->SetClipObject( pTransferObj
, NULL
);
283 bool bSuccess
= false;
284 aClipParam
.mbCutMode
= false;
289 // We con't support cutting of multi-selections.
293 // TODO: What's this for?
296 SAL_WNODEPRECATED_DECLARATIONS_PUSH
297 ::std::auto_ptr
<ScDocument
> pDocClip(new ScDocument(SCDOCMODE_CLIP
));
298 SAL_WNODEPRECATED_DECLARATIONS_POP
300 // Check for geometrical feasibility of the ranges.
301 bool bValidRanges
= true;
302 ScRange
* p
= aClipParam
.maRanges
.front();
303 SCCOL nPrevColDelta
= 0;
304 SCROW nPrevRowDelta
= 0;
305 SCCOL nPrevCol
= p
->aStart
.Col();
306 SCROW nPrevRow
= p
->aStart
.Row();
307 SCCOL nPrevColSize
= p
->aEnd
.Col() - p
->aStart
.Col() + 1;
308 SCROW nPrevRowSize
= p
->aEnd
.Row() - p
->aStart
.Row() + 1;
309 for ( size_t i
= 1; i
< aClipParam
.maRanges
.size(); ++i
)
311 p
= aClipParam
.maRanges
[i
];
312 if ( pDoc
->HasSelectedBlockMatrixFragment(
313 p
->aStart
.Col(), p
->aStart
.Row(), p
->aEnd
.Col(), p
->aEnd
.Row(), rMark
) )
316 ErrorMessage(STR_MATRIXFRAGMENTERR
);
320 SCCOL nColDelta
= p
->aStart
.Col() - nPrevCol
;
321 SCROW nRowDelta
= p
->aStart
.Row() - nPrevRow
;
323 if ((nColDelta
&& nRowDelta
) || (nPrevColDelta
&& nRowDelta
) || (nPrevRowDelta
&& nColDelta
))
325 bValidRanges
= false;
329 if (aClipParam
.meDirection
== ScClipParam::Unspecified
)
332 aClipParam
.meDirection
= ScClipParam::Column
;
334 aClipParam
.meDirection
= ScClipParam::Row
;
337 SCCOL nColSize
= p
->aEnd
.Col() - p
->aStart
.Col() + 1;
338 SCROW nRowSize
= p
->aEnd
.Row() - p
->aStart
.Row() + 1;
340 if (aClipParam
.meDirection
== ScClipParam::Column
&& nRowSize
!= nPrevRowSize
)
342 // column-oriented ranges must have identical row size.
343 bValidRanges
= false;
346 if (aClipParam
.meDirection
== ScClipParam::Row
&& nColSize
!= nPrevColSize
)
348 // likewise, row-oriented ranges must have identical
350 bValidRanges
= false;
354 nPrevCol
= p
->aStart
.Col();
355 nPrevRow
= p
->aStart
.Row();
356 nPrevColDelta
= nColDelta
;
357 nPrevRowDelta
= nRowDelta
;
358 nPrevColSize
= nColSize
;
359 nPrevRowSize
= nRowSize
;
363 pDoc
->CopyToClip(aClipParam
, pDocClip
.get(), &rMark
, false, false, bIncludeObjects
, true, bUseRangeForVBA
);
365 ScChangeTrack
* pChangeTrack
= pDoc
->GetChangeTrack();
367 pChangeTrack
->ResetLastCut(); // kein CutMode mehr
370 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
371 TransferableObjectDescriptor aObjDesc
;
372 pDocSh
->FillTransferableObjectDescriptor( aObjDesc
);
373 aObjDesc
.maDisplayName
= pDocSh
->GetMedium()->GetURLObject().GetURLNoPass();
374 // maSize is set in ScTransferObj ctor
376 ScTransferObj
* pTransferObj
= new ScTransferObj( pDocClip
.release(), aObjDesc
);
377 uno::Reference
<datatransfer::XTransferable
> xTransferable( pTransferObj
);
379 if ( ScGlobal::pDrawClipDocShellRef
)
381 SfxObjectShellRef
aPersistRef( &(*ScGlobal::pDrawClipDocShellRef
) );
382 pTransferObj
->SetDrawPersist( aPersistRef
); // keep persist for ole objects alive
385 pTransferObj
->CopyToClipboard( GetActiveWin() ); // system clipboard
386 SC_MOD()->SetClipObject( pTransferObj
, NULL
); // internal clipboard
393 if (!bSuccess
&& !bApi
)
394 ErrorMessage(STR_NOMULTISELECT
);
402 ScTransferObj
* ScViewFunc::CopyToTransferable()
405 if ( GetViewData()->GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
407 ScDocument
* pDoc
= GetViewData()->GetDocument();
408 ScMarkData
& rMark
= GetViewData()->GetMarkData();
409 if ( !pDoc
->HasSelectedBlockMatrixFragment(
410 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
411 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(),
414 ScDocument
*pClipDoc
= new ScDocument( SCDOCMODE_CLIP
); // create one (deleted by ScTransferObj)
416 bool bAnyOle
= pDoc
->HasOLEObjectsInArea( aRange
, &rMark
);
417 ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle
) );
419 ScClipParam
aClipParam(aRange
, false);
420 pDoc
->CopyToClip(aClipParam
, pClipDoc
, &rMark
, false, false, true);
422 ScDrawLayer::SetGlobalDrawPersist(NULL
);
423 pClipDoc
->ExtendMerge( aRange
, true );
425 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
426 TransferableObjectDescriptor aObjDesc
;
427 pDocSh
->FillTransferableObjectDescriptor( aObjDesc
);
428 aObjDesc
.maDisplayName
= pDocSh
->GetMedium()->GetURLObject().GetURLNoPass();
429 ScTransferObj
* pTransferObj
= new ScTransferObj( pClipDoc
, aObjDesc
);
440 void ScViewFunc::PasteDraw()
442 ScViewData
* pViewData
= GetViewData();
443 SCCOL nPosX
= pViewData
->GetCurX();
444 SCROW nPosY
= pViewData
->GetCurY();
445 Window
* pWin
= GetActiveWin();
446 Point aPos
= pWin
->PixelToLogic( pViewData
->GetScrPos( nPosX
, nPosY
,
447 pViewData
->GetActivePart() ) );
448 ScDrawTransferObj
* pDrawClip
= ScDrawTransferObj::GetOwnClipboard( pWin
);
451 OUString aSrcShellID
= pDrawClip
->GetShellID();
452 OUString aDestShellID
= SfxObjectShell::CreateShellID(pViewData
->GetDocShell());
453 PasteDraw(aPos
, pDrawClip
->GetModel(), false, aSrcShellID
, aDestShellID
);
457 void ScViewFunc::PasteFromSystem()
461 Window
* pWin
= GetActiveWin();
462 ScTransferObj
* pOwnClip
= ScTransferObj::GetOwnClipboard( pWin
);
463 ScDrawTransferObj
* pDrawClip
= ScDrawTransferObj::GetOwnClipboard( pWin
);
467 // keep a reference in case the clipboard is changed during PasteFromClip
468 uno::Reference
<datatransfer::XTransferable
> aOwnClipRef( pOwnClip
);
469 PasteFromClip( IDF_ALL
, pOwnClip
->GetDocument(),
470 PASTE_NOFUNC
, false, false, false, INS_NONE
, IDF_NONE
,
471 true ); // allow warning dialog
477 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin
) );
480 sal_uLong nBiff8
= SotExchange::RegisterFormatName(OUString("Biff8"));
481 sal_uLong nBiff5
= SotExchange::RegisterFormatName(OUString("Biff5"));
483 // als erstes SvDraw-Model, dann Grafik
484 // (Grafik darf nur bei einzelner Grafik drinstehen)
486 if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_DRAWING
))
488 // special case for tables from drawing
489 if( aDataHelper
.HasFormat( SOT_FORMAT_RTF
) )
491 PasteFromSystem( FORMAT_RTF
);
495 PasteFromSystem( SOT_FORMATSTR_ID_DRAWING
);
498 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SVXB
))
499 PasteFromSystem( SOT_FORMATSTR_ID_SVXB
);
500 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE
))
502 // If it's a Writer object, insert RTF instead of OLE
504 // Else, if the class id is all-zero, and SYLK is available,
505 // it probably is spreadsheet cells that have been put
506 // on the clipboard by OOo, so use the SYLK. (fdo#31077)
509 TransferableObjectDescriptor aObjDesc
;
510 if( aDataHelper
.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
, aObjDesc
) )
512 bDoRtf
= ( ( aObjDesc
.maClassName
== SvGlobalName( SO3_SW_CLASSID
) ||
513 aObjDesc
.maClassName
== SvGlobalName( SO3_SWWEB_CLASSID
) )
514 && aDataHelper
.HasFormat( SOT_FORMAT_RTF
) );
517 PasteFromSystem( FORMAT_RTF
);
518 else if ( aObjDesc
.maClassName
== SvGlobalName( 0,0,0,0,0,0,0,0,0,0,0 )
519 && aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SYLK
))
520 PasteFromSystem( SOT_FORMATSTR_ID_SYLK
);
522 PasteFromSystem( SOT_FORMATSTR_ID_EMBED_SOURCE
);
524 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE
))
525 PasteFromSystem( SOT_FORMATSTR_ID_LINK_SOURCE
);
526 // the following format can not affect scenario from #89579#
527 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
))
528 PasteFromSystem( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
);
529 // FORMAT_PRIVATE no longer here (can't work if pOwnClip is NULL)
530 else if (aDataHelper
.HasFormat(nBiff8
)) // before xxx_OLE formats
531 PasteFromSystem(nBiff8
);
532 else if (aDataHelper
.HasFormat(nBiff5
))
533 PasteFromSystem(nBiff5
);
534 else if (aDataHelper
.HasFormat(FORMAT_RTF
))
535 PasteFromSystem(FORMAT_RTF
);
536 else if (aDataHelper
.HasFormat(SOT_FORMATSTR_ID_HTML
))
537 PasteFromSystem(SOT_FORMATSTR_ID_HTML
);
538 else if (aDataHelper
.HasFormat(SOT_FORMATSTR_ID_HTML_SIMPLE
))
539 PasteFromSystem(SOT_FORMATSTR_ID_HTML_SIMPLE
);
540 else if (aDataHelper
.HasFormat(SOT_FORMATSTR_ID_SYLK
))
541 PasteFromSystem(SOT_FORMATSTR_ID_SYLK
);
542 else if (aDataHelper
.HasFormat(FORMAT_STRING
))
543 PasteFromSystem(FORMAT_STRING
);
544 else if (aDataHelper
.HasFormat(FORMAT_GDIMETAFILE
))
545 PasteFromSystem(FORMAT_GDIMETAFILE
);
546 else if (aDataHelper
.HasFormat(FORMAT_BITMAP
))
547 PasteFromSystem(FORMAT_BITMAP
);
548 // xxx_OLE formats come last, like in SotExchange tables
549 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
))
550 PasteFromSystem( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
);
551 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
))
552 PasteFromSystem( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
);
555 // keine Fehlermeldung, weil SID_PASTE in der idl das FastCall-Flag hat,
556 // also auch gerufen wird, wenn nichts im Clipboard steht (#42531#)
559 void ScViewFunc::PasteFromTransferable( const uno::Reference
<datatransfer::XTransferable
>& rxTransferable
)
561 ScTransferObj
*pOwnClip
=0;
562 ScDrawTransferObj
*pDrawClip
=0;
563 uno::Reference
<lang::XUnoTunnel
> xTunnel( rxTransferable
, uno::UNO_QUERY
);
566 sal_Int64 nHandle
= xTunnel
->getSomething( ScTransferObj::getUnoTunnelId() );
568 pOwnClip
= (ScTransferObj
*) (sal_IntPtr
) nHandle
;
571 nHandle
= xTunnel
->getSomething( ScDrawTransferObj::getUnoTunnelId() );
573 pDrawClip
= (ScDrawTransferObj
*) (sal_IntPtr
) nHandle
;
579 PasteFromClip( IDF_ALL
, pOwnClip
->GetDocument(),
580 PASTE_NOFUNC
, false, false, false, INS_NONE
, IDF_NONE
,
581 true ); // allow warning dialog
585 ScViewData
* pViewData
= GetViewData();
586 SCCOL nPosX
= pViewData
->GetCurX();
587 SCROW nPosY
= pViewData
->GetCurY();
588 Window
* pWin
= GetActiveWin();
589 Point aPos
= pWin
->PixelToLogic( pViewData
->GetScrPos( nPosX
, nPosY
, pViewData
->GetActivePart() ) );
591 aPos
, pDrawClip
->GetModel(), false,
592 pDrawClip
->GetShellID(), SfxObjectShell::CreateShellID(pViewData
->GetDocShell()));
596 TransferableDataHelper
aDataHelper( rxTransferable
);
598 sal_uLong nBiff8
= SotExchange::RegisterFormatName(OUString("Biff8"));
599 sal_uLong nBiff5
= SotExchange::RegisterFormatName(OUString("Biff5"));
600 sal_uLong nFormatId
= 0;
601 // als erstes SvDraw-Model, dann Grafik
602 // (Grafik darf nur bei einzelner Grafik drinstehen)
604 if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_DRAWING
))
605 nFormatId
= SOT_FORMATSTR_ID_DRAWING
;
606 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SVXB
))
607 nFormatId
= SOT_FORMATSTR_ID_SVXB
;
608 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE
))
610 // If it's a Writer object, insert RTF instead of OLE
612 TransferableObjectDescriptor aObjDesc
;
613 if( aDataHelper
.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
, aObjDesc
) )
615 bDoRtf
= ( ( aObjDesc
.maClassName
== SvGlobalName( SO3_SW_CLASSID
) ||
616 aObjDesc
.maClassName
== SvGlobalName( SO3_SWWEB_CLASSID
) )
617 && aDataHelper
.HasFormat( SOT_FORMAT_RTF
) );
620 nFormatId
= FORMAT_RTF
;
622 nFormatId
= SOT_FORMATSTR_ID_EMBED_SOURCE
;
624 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE
))
625 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE
;
626 // the following format can not affect scenario from #89579#
627 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
))
628 nFormatId
= SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
;
629 // FORMAT_PRIVATE no longer here (can't work if pOwnClip is NULL)
630 else if (aDataHelper
.HasFormat(nBiff8
)) // before xxx_OLE formats
632 else if (aDataHelper
.HasFormat(nBiff5
))
634 else if (aDataHelper
.HasFormat(FORMAT_RTF
))
635 nFormatId
= FORMAT_RTF
;
636 else if (aDataHelper
.HasFormat(SOT_FORMATSTR_ID_HTML
))
637 nFormatId
= SOT_FORMATSTR_ID_HTML
;
638 else if (aDataHelper
.HasFormat(SOT_FORMATSTR_ID_HTML_SIMPLE
))
639 nFormatId
= SOT_FORMATSTR_ID_HTML_SIMPLE
;
640 else if (aDataHelper
.HasFormat(SOT_FORMATSTR_ID_SYLK
))
641 nFormatId
= SOT_FORMATSTR_ID_SYLK
;
642 else if (aDataHelper
.HasFormat(FORMAT_STRING
))
643 nFormatId
= FORMAT_STRING
;
644 else if (aDataHelper
.HasFormat(FORMAT_GDIMETAFILE
))
645 nFormatId
= FORMAT_GDIMETAFILE
;
646 else if (aDataHelper
.HasFormat(FORMAT_BITMAP
))
647 nFormatId
= FORMAT_BITMAP
;
648 // xxx_OLE formats come last, like in SotExchange tables
649 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
))
650 nFormatId
= SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
;
651 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
))
652 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE_OLE
;
656 PasteDataFormat( nFormatId
, aDataHelper
.GetTransferable(),
657 GetViewData()->GetCurX(), GetViewData()->GetCurY(),
658 NULL
, false, false );
663 bool ScViewFunc::PasteFromSystem( sal_uLong nFormatId
, bool bApi
)
668 Window
* pWin
= GetActiveWin();
669 ScTransferObj
* pOwnClip
= ScTransferObj::GetOwnClipboard( pWin
);
670 if ( nFormatId
== 0 && pOwnClip
)
672 // keep a reference in case the clipboard is changed during PasteFromClip
673 uno::Reference
<datatransfer::XTransferable
> aOwnClipRef( pOwnClip
);
674 PasteFromClip( IDF_ALL
, pOwnClip
->GetDocument(),
675 PASTE_NOFUNC
, false, false, false, INS_NONE
, IDF_NONE
,
676 !bApi
); // allow warning dialog
680 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin
) );
681 if ( !aDataHelper
.GetTransferable().is() )
687 ScViewData
* pViewData
= GetViewData();
689 if ( pViewData
->GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
691 nPosX
= aRange
.aStart
.Col();
692 nPosY
= aRange
.aStart
.Row();
696 nPosX
= pViewData
->GetCurX();
697 nPosY
= pViewData
->GetCurY();
700 bRet
= PasteDataFormat( nFormatId
, aDataHelper
.GetTransferable(),
702 NULL
, false, !bApi
); // allow warning dialog
704 if ( !bRet
&& !bApi
)
705 ErrorMessage(STR_PASTE_ERROR
);
712 bool ScViewFunc::PasteOnDrawObjectLinked(
713 const uno::Reference
<datatransfer::XTransferable
>& rxTransferable
,
716 TransferableDataHelper
aDataHelper( rxTransferable
);
718 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SVXB
) )
720 SotStorageStreamRef xStm
;
721 ScDrawView
* pScDrawView
= GetScDrawView();
723 if( pScDrawView
&& aDataHelper
.GetSotStorageStream( SOT_FORMATSTR_ID_SVXB
, xStm
) )
727 ReadGraphic( *xStm
, aGraphic
);
729 const OUString aEmpty
;
730 const OUString
aBeginUndo(ScGlobal::GetRscString(STR_UNDO_DRAGDROP
));
732 if(pScDrawView
->ApplyGraphicToObject( rHitObj
, aGraphic
, aBeginUndo
, aEmpty
, aEmpty
))
738 else if ( aDataHelper
.HasFormat( SOT_FORMAT_GDIMETAFILE
) )
741 ScDrawView
* pScDrawView
= GetScDrawView();
743 if( pScDrawView
&& aDataHelper
.GetGDIMetaFile( FORMAT_GDIMETAFILE
, aMtf
) )
745 const OUString aEmpty
;
746 const OUString
aBeginUndo(ScGlobal::GetRscString(STR_UNDO_DRAGDROP
));
748 if(pScDrawView
->ApplyGraphicToObject( rHitObj
, Graphic(aMtf
), aBeginUndo
, aEmpty
, aEmpty
))
754 else if ( aDataHelper
.HasFormat( SOT_FORMAT_BITMAP
) || aDataHelper
.HasFormat( SOT_FORMATSTR_ID_PNG
) )
757 ScDrawView
* pScDrawView
= GetScDrawView();
759 if( pScDrawView
&& aDataHelper
.GetBitmapEx( FORMAT_BITMAP
, aBmpEx
) )
761 const OUString aEmpty
;
762 const OUString
aBeginUndo(ScGlobal::GetRscString(STR_UNDO_DRAGDROP
));
764 if(pScDrawView
->ApplyGraphicToObject( rHitObj
, Graphic(aBmpEx
), aBeginUndo
, aEmpty
, aEmpty
))
774 static bool lcl_SelHasAttrib( ScDocument
* pDoc
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
775 const ScMarkData
& rTabSelection
, sal_uInt16 nMask
)
777 ScMarkData::const_iterator itr
= rTabSelection
.begin(), itrEnd
= rTabSelection
.end();
778 for (; itr
!= itrEnd
; ++itr
)
779 if ( pDoc
->HasAttrib( nCol1
, nRow1
, *itr
, nCol2
, nRow2
, *itr
, nMask
) )
785 // Einfuegen auf Tabelle:
792 bool checkDestRangeForOverwrite(const ScRangeList
& rDestRanges
, const ScDocument
* pDoc
, const ScMarkData
& rMark
, Window
* pParentWnd
)
794 bool bIsEmpty
= true;
795 ScMarkData::const_iterator itrTab
= rMark
.begin(), itrTabEnd
= rMark
.end();
796 size_t nRangeSize
= rDestRanges
.size();
797 for (; itrTab
!= itrTabEnd
&& bIsEmpty
; ++itrTab
)
799 for (size_t i
= 0; i
< nRangeSize
&& bIsEmpty
; ++i
)
801 const ScRange
& rRange
= *rDestRanges
[i
];
802 bIsEmpty
= pDoc
->IsBlockEmpty(
803 *itrTab
, rRange
.aStart
.Col(), rRange
.aStart
.Row(),
804 rRange
.aEnd
.Col(), rRange
.aEnd
.Row());
810 ScReplaceWarnBox
aBox(pParentWnd
);
811 if (aBox
.Execute() != RET_YES
)
813 // changing the configuration is within the ScReplaceWarnBox
822 bool ScViewFunc::PasteFromClip( sal_uInt16 nFlags
, ScDocument
* pClipDoc
,
823 sal_uInt16 nFunction
, bool bSkipEmpty
,
824 bool bTranspose
, bool bAsLink
,
825 InsCellCmd eMoveMode
, sal_uInt16 nUndoExtraFlags
,
830 OSL_FAIL("PasteFromClip: pClipDoc=0 not allowed");
834 // fuer Undo etc. immer alle oder keine Inhalte sichern
835 sal_uInt16 nContFlags
= IDF_NONE
;
836 if (nFlags
& IDF_CONTENTS
)
837 nContFlags
|= IDF_CONTENTS
;
838 if (nFlags
& IDF_ATTRIB
)
839 nContFlags
|= IDF_ATTRIB
;
840 // evtl. Attribute ins Undo ohne sie vom Clip ins Doc zu kopieren
841 sal_uInt16 nUndoFlags
= nContFlags
;
842 if (nUndoExtraFlags
& IDF_ATTRIB
)
843 nUndoFlags
|= IDF_ATTRIB
;
844 // do not copy note captions into undo document
845 nUndoFlags
|= IDF_NOCAPTIONS
;
847 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
848 if (rClipParam
.isMultiRange())
850 // Source data is multi-range.
851 return PasteMultiRangesFromClip(
852 nFlags
, pClipDoc
, nFunction
, bSkipEmpty
, bTranspose
, bAsLink
, bAllowDialogs
,
853 eMoveMode
, nUndoFlags
);
856 ScMarkData
& rMark
= GetViewData()->GetMarkData();
857 if (rMark
.IsMultiMarked())
859 // Source data is single-range but destination is multi-range.
860 return PasteFromClipToMultiRanges(
861 nFlags
, pClipDoc
, nFunction
, bSkipEmpty
, bTranspose
, bAsLink
, bAllowDialogs
,
862 eMoveMode
, nUndoFlags
);
865 bool bCutMode
= pClipDoc
->IsCutMode(); // if transposing, take from original clipdoc
866 bool bIncludeFiltered
= bCutMode
;
868 // paste drawing: also if IDF_NOTE is set (to create drawing layer for note captions)
869 bool bPasteDraw
= ( pClipDoc
->GetDrawLayer() && ( nFlags
& (IDF_OBJECTS
|IDF_NOTE
) ) );
871 ScDocShellRef aTransShellRef
; // for objects in xTransClip - must remain valid as long as xTransClip
872 ScDocument
* pOrigClipDoc
= NULL
;
873 SAL_WNODEPRECATED_DECLARATIONS_PUSH
874 ::std::auto_ptr
< ScDocument
> xTransClip
;
875 SAL_WNODEPRECATED_DECLARATIONS_POP
880 // include filtered rows until TransposeClip can skip them
881 bIncludeFiltered
= true;
882 pClipDoc
->GetClipArea( nX
, nY
, true );
883 if ( nY
> static_cast<sal_Int32
>(MAXCOL
) ) // zuviele Zeilen zum Transponieren
885 ErrorMessage(STR_PASTE_FULL
);
888 pOrigClipDoc
= pClipDoc
; // fuer Referenzen
892 aTransShellRef
= new ScDocShell
; // DocShell needs a Ref immediately
893 aTransShellRef
->DoInitNew(NULL
);
895 ScDrawLayer::SetGlobalDrawPersist(aTransShellRef
);
897 xTransClip
.reset( new ScDocument( SCDOCMODE_CLIP
));
898 pClipDoc
->TransposeClip( xTransClip
.get(), nFlags
, bAsLink
);
899 pClipDoc
= xTransClip
.get();
901 ScDrawLayer::SetGlobalDrawPersist(NULL
);
912 pClipDoc
->GetClipArea( nClipSizeX
, nClipSizeY
, true ); // size in clipboard doc
914 // size in target doc: include filtered rows only if CutMode is set
917 pClipDoc
->GetClipArea( nDestSizeX
, nDestSizeY
, bIncludeFiltered
);
919 ScDocument
* pDoc
= GetViewData()->GetDocument();
920 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
921 ::svl::IUndoManager
* pUndoMgr
= pDocSh
->GetUndoManager();
922 const bool bRecord(pDoc
->IsUndoEnabled());
924 ScDocShellModificator
aModificator( *pDocSh
);
927 ScMarkData
aFilteredMark( rMark
); // local copy for all modifications
928 ScMarkType eMarkType
= GetViewData()->GetSimpleArea( aMarkRange
, aFilteredMark
);
929 bool bMarkIsFiltered
= (eMarkType
== SC_MARK_SIMPLE_FILTERED
);
930 bool bNoPaste
= ((eMarkType
!= SC_MARK_SIMPLE
&& !bMarkIsFiltered
) ||
931 (bMarkIsFiltered
&& (eMoveMode
!= INS_NONE
|| bAsLink
)));
935 if (!rMark
.IsMarked())
937 // Create a selection with clipboard row count and check that for
939 nStartCol
= GetViewData()->GetCurX();
940 nStartRow
= GetViewData()->GetCurY();
941 nStartTab
= GetViewData()->GetTabNo();
942 nEndCol
= nStartCol
+ nDestSizeX
;
943 nEndRow
= nStartRow
+ nDestSizeY
;
945 aMarkRange
= ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
946 if (ScViewUtil::HasFiltered( aMarkRange
, pDoc
))
948 bMarkIsFiltered
= true;
949 // Fit to clipboard's row count unfiltered rows. If there is no
950 // fit assume that pasting is not possible. Note that nDestSizeY is
951 // size-1 (difference).
952 if (!ScViewUtil::FitToUnfilteredRows( aMarkRange
, pDoc
, nDestSizeY
+1))
955 aFilteredMark
.SetMarkArea( aMarkRange
);
959 // Expand the marked area when the destination area is larger than the
960 // current selection, to get the undo do the right thing. (i#106711)
962 aFilteredMark
.GetMarkArea( aRange
);
963 if( (aRange
.aEnd
.Col() - aRange
.aStart
.Col()) < nDestSizeX
)
965 aRange
.aEnd
.SetCol(aRange
.aStart
.Col() + nDestSizeX
);
966 aFilteredMark
.SetMarkArea(aRange
);
973 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
977 SCROW nUnfilteredRows
= aMarkRange
.aEnd
.Row() - aMarkRange
.aStart
.Row() + 1;
978 ScRangeList aRangeList
;
981 ScViewUtil::UnmarkFiltered( aFilteredMark
, pDoc
);
982 aFilteredMark
.FillRangeListWithMarks( &aRangeList
, false);
984 size_t ListSize
= aRangeList
.size();
985 for ( size_t i
= 0; i
< ListSize
; ++i
)
987 ScRange
* p
= aRangeList
[i
];
988 nUnfilteredRows
+= p
->aEnd
.Row() - p
->aStart
.Row() + 1;
991 /* This isn't needed but could be a desired restriction. */
992 // For filtered, destination rows have to be an exact multiple of
993 // source rows. Note that nDestSizeY is size-1 (difference), so
994 // nDestSizeY==0 fits always.
995 if ((nUnfilteredRows
% (nDestSizeY
+1)) != 0)
997 /* FIXME: this should be a more descriptive error message then. */
998 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
1004 // Also for a filtered selection the area is used, for undo et al.
1005 if ( aFilteredMark
.IsMarked() || bMarkIsFiltered
)
1007 aMarkRange
.GetVars( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
1008 SCCOL nBlockAddX
= nEndCol
-nStartCol
;
1009 SCROW nBlockAddY
= nEndRow
-nStartRow
;
1011 // Nachfrage, wenn die Selektion groesser als 1 Zeile/Spalte, aber kleiner
1012 // als das Clipboard ist (dann wird ueber die Selektion hinaus eingefuegt)
1014 // ClipSize is not size, but difference
1015 if ( ( nBlockAddX
!= 0 && nBlockAddX
< nDestSizeX
) ||
1016 ( nBlockAddY
!= 0 && nBlockAddY
< nDestSizeY
) ||
1017 ( bMarkIsFiltered
&& nUnfilteredRows
< nDestSizeY
+1 ) )
1019 ScWaitCursorOff
aWaitOff( GetFrameWin() );
1020 OUString aMessage
= ScGlobal::GetRscString( STR_PASTE_BIGGER
);
1021 QueryBox
aBox( GetViewData()->GetDialogParent(),
1022 WinBits(WB_YES_NO
| WB_DEF_NO
), aMessage
);
1023 if ( aBox
.Execute() != RET_YES
)
1029 if (nBlockAddX
<= nDestSizeX
)
1030 nEndCol
= nStartCol
+ nDestSizeX
;
1032 if (nBlockAddY
<= nDestSizeY
)
1034 nEndRow
= nStartRow
+ nDestSizeY
;
1035 if (bMarkIsFiltered
|| nEndRow
> aMarkRange
.aEnd
.Row())
1037 // Same as above if nothing was marked: re-fit selection to
1038 // unfiltered rows. Extending the selection actually may
1039 // introduce filtered rows where there weren't any before, so
1040 // we also need to test for that.
1041 aMarkRange
= ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
1042 if (bMarkIsFiltered
|| ScViewUtil::HasFiltered( aMarkRange
, pDoc
))
1044 bMarkIsFiltered
= true;
1045 // Worst case: all rows up to the end of the sheet are filtered.
1046 if (!ScViewUtil::FitToUnfilteredRows( aMarkRange
, pDoc
, nDestSizeY
+1))
1048 ErrorMessage(STR_PASTE_FULL
);
1052 aMarkRange
.GetVars( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
1053 aFilteredMark
.SetMarkArea( aMarkRange
);
1054 if (bMarkIsFiltered
)
1056 ScViewUtil::UnmarkFiltered( aFilteredMark
, pDoc
);
1057 aFilteredMark
.FillRangeListWithMarks( &aRangeList
, true);
1064 nStartCol
= GetViewData()->GetCurX();
1065 nStartRow
= GetViewData()->GetCurY();
1066 nStartTab
= GetViewData()->GetTabNo();
1067 nEndCol
= nStartCol
+ nDestSizeX
;
1068 nEndRow
= nStartRow
+ nDestSizeY
;
1069 nEndTab
= nStartTab
;
1072 bool bOffLimits
= !ValidCol(nEndCol
) || !ValidRow(nEndRow
);
1074 // Zielbereich, wie er angezeigt wird:
1075 ScRange
aUserRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
1077 // Sollen Zellen eingefuegt werden?
1078 // (zu grosse nEndCol/nEndRow werden weiter unten erkannt)
1079 bool bInsertCells
= ( eMoveMode
!= INS_NONE
&& !bOffLimits
);
1082 // Instead of EnterListAction, the paste undo action is merged into the
1083 // insert action, so Repeat can insert the right cells
1085 MarkRange( aUserRange
); // wird vor CopyFromClip sowieso gesetzt
1087 // CutMode is reset on insertion of cols/rows but needed again on cell move
1088 bool bCut
= pClipDoc
->IsCutMode();
1089 if (!InsertCells( eMoveMode
, bRecord
, true )) // is inserting possible?
1092 // #i21036# EnterListAction isn't used, and InsertCells doesn't insert
1093 // its undo action on failure, so no undo handling is needed here
1096 pClipDoc
->SetCutMode( bCut
);
1098 else if (!bOffLimits
)
1100 bool bAskIfNotEmpty
= bAllowDialogs
&&
1101 ( nFlags
& IDF_CONTENTS
) &&
1102 nFunction
== PASTE_NOFUNC
&&
1103 SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1104 if ( bAskIfNotEmpty
)
1106 ScRangeList aTestRanges
;
1107 aTestRanges
.Append(aUserRange
);
1108 if (!checkDestRangeForOverwrite(aTestRanges
, pDoc
, aFilteredMark
, GetViewData()->GetDialogParent()))
1113 SCCOL nClipStartX
; // Clipboard-Bereich erweitern
1115 pClipDoc
->GetClipStart( nClipStartX
, nClipStartY
);
1116 SCCOL nUndoEndCol
= nClipStartX
+ nClipSizeX
;
1117 SCROW nUndoEndRow
= nClipStartY
+ nClipSizeY
; // end of source area in clipboard document
1118 bool bClipOver
= false;
1119 // #i68690# ExtendMerge for the clip doc must be called with the clipboard's sheet numbers.
1120 // The same end column/row can be used for all calls because the clip doc doesn't contain
1121 // content outside the clip area.
1122 for (SCTAB nClipTab
=0; nClipTab
< pClipDoc
->GetTableCount(); nClipTab
++)
1123 if ( pClipDoc
->HasTable(nClipTab
) )
1124 if ( pClipDoc
->ExtendMerge( nClipStartX
,nClipStartY
, nUndoEndCol
,nUndoEndRow
, nClipTab
, false ) )
1126 nUndoEndCol
-= nClipStartX
+ nClipSizeX
;
1127 nUndoEndRow
-= nClipStartY
+ nClipSizeY
; // now contains only the difference added by ExtendMerge
1128 nUndoEndCol
= sal::static_int_cast
<SCCOL
>( nUndoEndCol
+ nEndCol
);
1129 nUndoEndRow
= sal::static_int_cast
<SCROW
>( nUndoEndRow
+ nEndRow
); // destination area, expanded for merged cells
1131 if (nUndoEndCol
>MAXCOL
|| nUndoEndRow
>MAXROW
)
1133 ErrorMessage(STR_PASTE_FULL
);
1137 pDoc
->ExtendMergeSel( nStartCol
,nStartRow
, nUndoEndCol
,nUndoEndRow
, aFilteredMark
, false );
1139 // Test auf Zellschutz
1141 ScEditableTester
aTester( pDoc
, nStartTab
, nStartCol
,nStartRow
, nUndoEndCol
,nUndoEndRow
);
1142 if (!aTester
.IsEditable())
1144 ErrorMessage(aTester
.GetMessageId());
1148 //! Test auf Ueberlappung
1149 //! nur wirkliche Schnittmenge testen !!!!!!!
1151 ScDocFunc
& rDocFunc
= pDocSh
->GetDocFunc();
1154 OUString aUndo
= ScGlobal::GetRscString( pClipDoc
->IsCutMode() ? STR_UNDO_MOVE
: STR_UNDO_COPY
);
1155 pUndoMgr
->EnterListAction( aUndo
, aUndo
);
1159 if (lcl_SelHasAttrib( pDoc
, nStartCol
,nStartRow
, nUndoEndCol
,nUndoEndRow
, aFilteredMark
, HASATTR_OVERLAPPED
))
1160 { // "Cell merge not possible if cells already merged"
1161 ScDocAttrIterator
aIter( pDoc
, nStartTab
, nStartCol
, nStartRow
, nUndoEndCol
, nUndoEndRow
);
1162 const ScPatternAttr
* pPattern
= NULL
;
1163 const ScMergeAttr
* pMergeFlag
= NULL
;
1164 const ScMergeFlagAttr
* pMergeFlagAttr
= NULL
;
1168 while ( ( pPattern
= aIter
.GetNext( nCol
, nRow1
, nRow2
) ) != NULL
)
1170 pMergeFlag
= (const ScMergeAttr
*) &pPattern
->GetItem(ATTR_MERGE
);
1171 pMergeFlagAttr
= (const ScMergeFlagAttr
*) &pPattern
->GetItem(ATTR_MERGE_FLAG
);
1172 if( ( pMergeFlag
&& pMergeFlag
->IsMerged() ) || ( pMergeFlagAttr
&& pMergeFlagAttr
->IsOverlapped() ) )
1174 ScRange
aRange(nCol
, nRow1
, nStartTab
);
1175 pDoc
->ExtendOverlapped(aRange
);
1176 pDoc
->ExtendMerge(aRange
, true);
1177 rDocFunc
.UnmergeCells(aRange
, bRecord
);
1184 ScChangeTrack
* pChangeTrack
= pDoc
->GetChangeTrack();
1186 pChangeTrack
->ResetLastCut(); // kein CutMode mehr
1189 bool bColInfo
= ( nStartRow
==0 && nEndRow
==MAXROW
);
1190 bool bRowInfo
= ( nStartCol
==0 && nEndCol
==MAXCOL
);
1192 ScDocument
* pUndoDoc
= NULL
;
1193 ScDocument
* pRefUndoDoc
= NULL
;
1194 ScRefUndoData
* pUndoData
= NULL
;
1198 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1199 pUndoDoc
->InitUndoSelected( pDoc
, aFilteredMark
, bColInfo
, bRowInfo
);
1201 // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
1202 SCTAB nTabCount
= pDoc
->GetTableCount();
1203 pDoc
->CopyToDocument( nStartCol
, nStartRow
, 0, nUndoEndCol
, nUndoEndRow
, nTabCount
-1,
1204 nUndoFlags
, false, pUndoDoc
);
1208 pRefUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1209 pRefUndoDoc
->InitUndo( pDoc
, 0, nTabCount
-1, false, false );
1211 pUndoData
= new ScRefUndoData( pDoc
);
1215 sal_uInt16 nExtFlags
= 0;
1216 pDocSh
->UpdatePaintExt( nExtFlags
, nStartCol
, nStartRow
, nStartTab
,
1217 nEndCol
, nEndRow
, nEndTab
); // content before the change
1219 if (GetViewData()->IsActive())
1224 rMark
.SetMarkArea( aUserRange
);
1228 // Aus Clipboard kopieren,
1229 // wenn gerechnet werden soll, Originaldaten merken
1232 boost::scoped_ptr
<ScDocument
> pMixDoc
;
1236 if ( nFlags
& IDF_CONTENTS
)
1238 pMixDoc
.reset(new ScDocument( SCDOCMODE_UNDO
));
1239 pMixDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
);
1240 pDoc
->CopyToDocument( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
,
1241 IDF_CONTENTS
, false, pMixDoc
.get() );
1245 /* Make draw layer and start drawing undo.
1246 - Needed before AdjustBlockHeight to track moved drawing objects.
1247 - Needed before pDoc->CopyFromClip to track inserted note caption objects.
1250 pDocSh
->MakeDrawLayer();
1252 pDoc
->BeginDrawUndo();
1254 sal_uInt16 nNoObjFlags
= nFlags
& ~IDF_OBJECTS
;
1257 // copy normally (original range)
1258 pDoc
->CopyFromClip( aUserRange
, aFilteredMark
, nNoObjFlags
,
1259 pRefUndoDoc
, pClipDoc
, true, false, bIncludeFiltered
,
1260 bSkipEmpty
, (bMarkIsFiltered
? &aRangeList
: NULL
) );
1262 // bei Transpose Referenzen per Hand anpassen
1263 if ( bTranspose
&& bCutMode
&& (nFlags
& IDF_CONTENTS
) )
1264 pDoc
->UpdateTranspose( aUserRange
.aStart
, pOrigClipDoc
, aFilteredMark
, pRefUndoDoc
);
1266 else if (!bTranspose
)
1268 // copy with bAsLink=TRUE
1269 pDoc
->CopyFromClip( aUserRange
, aFilteredMark
, nNoObjFlags
, pRefUndoDoc
, pClipDoc
,
1270 true, true, bIncludeFiltered
, bSkipEmpty
);
1274 // alle Inhalte kopieren (im TransClipDoc stehen nur Formeln)
1275 pDoc
->CopyFromClip( aUserRange
, aFilteredMark
, nContFlags
, pRefUndoDoc
, pClipDoc
);
1278 // skipped rows and merged cells don't mix
1279 if ( !bIncludeFiltered
&& pClipDoc
->HasClipFilteredRows() )
1280 rDocFunc
.UnmergeCells( aUserRange
, false );
1282 pDoc
->ExtendMergeSel( nStartCol
, nStartRow
, nEndCol
, nEndRow
, aFilteredMark
, true ); // Refresh
1285 if ( pMixDoc
) // Rechenfunktionen mit Original-Daten auszufuehren ?
1287 pDoc
->MixDocument( aUserRange
, nFunction
, bSkipEmpty
, pMixDoc
.get() );
1291 AdjustBlockHeight(); // update row heights before pasting objects
1293 ::std::vector
< OUString
> aExcludedChartNames
;
1294 SdrPage
* pPage
= NULL
;
1296 if ( nFlags
& IDF_OBJECTS
)
1298 ScDrawView
* pScDrawView
= GetScDrawView();
1299 SdrModel
* pModel
= ( pScDrawView
? pScDrawView
->GetModel() : NULL
);
1300 pPage
= ( pModel
? pModel
->GetPage( static_cast< sal_uInt16
>( nStartTab
) ) : NULL
);
1303 ScChartHelper::GetChartNames( aExcludedChartNames
, pPage
);
1306 // Paste the drawing objects after the row heights have been updated.
1308 pDoc
->CopyFromClip( aUserRange
, aFilteredMark
, IDF_OBJECTS
, pRefUndoDoc
, pClipDoc
,
1309 true, false, bIncludeFiltered
);
1312 pDocSh
->UpdatePaintExt( nExtFlags
, nStartCol
, nStartRow
, nStartTab
,
1313 nEndCol
, nEndRow
, nEndTab
); // content after the change
1315 // ggf. Autofilter-Koepfe loeschen
1317 if (pDoc
->RefreshAutoFilter( nClipStartX
,nClipStartY
, nClipStartX
+nClipSizeX
,
1318 nClipStartY
+nClipSizeY
, nStartTab
))
1321 ScRange(nClipStartX
, nClipStartY
, nStartTab
, nClipStartX
+nClipSizeX
, nClipStartY
, nStartTab
),
1325 //! Block-Bereich bei RefUndoDoc weglassen !!!
1329 ScDocument
* pRedoDoc
= NULL
;
1330 // Redo-Daten werden erst beim ersten Undo kopiert
1331 // ohne RefUndoDoc muss das Redo-Doc noch nicht angelegt werden
1335 pRedoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1336 pRedoDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
, bColInfo
, bRowInfo
);
1338 // angepasste Referenzen ins Redo-Doc
1340 SCTAB nTabCount
= pDoc
->GetTableCount();
1341 pRedoDoc
->AddUndoTab( 0, nTabCount
-1 );
1342 pDoc
->CopyUpdated( pRefUndoDoc
, pRedoDoc
);
1344 // alte Referenzen ins Undo-Doc
1346 //! Tabellen selektieren ?
1347 pUndoDoc
->AddUndoTab( 0, nTabCount
-1 );
1348 pRefUndoDoc
->DeleteArea( nStartCol
, nStartRow
, nEndCol
, nEndRow
, aFilteredMark
, IDF_ALL
);
1349 pRefUndoDoc
->CopyToDocument( 0,0,0, MAXCOL
,MAXROW
,nTabCount
-1,
1350 IDF_FORMULA
, false, pUndoDoc
);
1354 // DeleteUnchanged for pUndoData is in ScUndoPaste ctor,
1355 // UndoData for redo is made during first undo
1357 ScUndoPasteOptions aOptions
; // store options for repeat
1358 aOptions
.nFunction
= nFunction
;
1359 aOptions
.bSkipEmpty
= bSkipEmpty
;
1360 aOptions
.bTranspose
= bTranspose
;
1361 aOptions
.bAsLink
= bAsLink
;
1362 aOptions
.eMoveMode
= eMoveMode
;
1364 SfxUndoAction
* pUndo
= new ScUndoPaste(
1365 pDocSh
, ScRange(nStartCol
, nStartRow
, nStartTab
, nUndoEndCol
, nUndoEndRow
, nEndTab
),
1366 aFilteredMark
, pUndoDoc
, pRedoDoc
, nFlags
| nUndoFlags
, pUndoData
,
1367 false, &aOptions
); // false = Redo data not yet copied
1371 // Merge the paste undo action into the insert action.
1372 // Use ScUndoWrapper so the ScUndoPaste pointer can be stored in the insert action.
1374 pUndoMgr
->AddUndoAction( new ScUndoWrapper( pUndo
), true );
1377 pUndoMgr
->AddUndoAction( pUndo
);
1378 pUndoMgr
->LeaveListAction();
1381 sal_uInt16 nPaint
= PAINT_GRID
;
1384 nPaint
|= PAINT_TOP
;
1385 nUndoEndCol
= MAXCOL
; // nur zum Zeichnen !
1389 nPaint
|= PAINT_LEFT
;
1390 nUndoEndRow
= MAXROW
; // nur zum Zeichnen !
1393 ScRange(nStartCol
, nStartRow
, nStartTab
, nUndoEndCol
, nUndoEndRow
, nEndTab
),
1395 // AdjustBlockHeight has already been called above
1398 aModificator
.SetDocumentModified();
1399 PostPasteFromClip(aUserRange
, rMark
);
1401 if ( nFlags
& IDF_OBJECTS
)
1403 ScModelObj
* pModelObj
= ScModelObj::getImplementation( pDocSh
->GetModel() );
1404 if ( pPage
&& pModelObj
)
1406 bool bSameDoc
= ( rClipParam
.getSourceDocID() == pDoc
->GetDocumentID() );
1407 const ScRangeListVector
& rProtectedChartRangesVector( rClipParam
.maProtectedChartRangesVector
);
1408 ScChartHelper::CreateProtectedChartListenersAndNotify( pDoc
, pPage
, pModelObj
, nStartTab
,
1409 rProtectedChartRangesVector
, aExcludedChartNames
, bSameDoc
);
1416 bool ScViewFunc::PasteMultiRangesFromClip(
1417 sal_uInt16 nFlags
, ScDocument
* pClipDoc
, sal_uInt16 nFunction
,
1418 bool bSkipEmpty
, bool bTranspose
, bool bAsLink
, bool bAllowDialogs
,
1419 InsCellCmd eMoveMode
, sal_uInt16 nUndoFlags
)
1421 ScViewData
& rViewData
= *GetViewData();
1422 ScDocument
* pDoc
= rViewData
.GetDocument();
1423 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
1424 ScMarkData
aMark(rViewData
.GetMarkData());
1425 const ScAddress
& rCurPos
= rViewData
.GetCurPos();
1426 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
1427 SCCOL nColSize
= rClipParam
.getPasteColSize();
1428 SCROW nRowSize
= rClipParam
.getPasteRowSize();
1432 if (static_cast<SCROW
>(rCurPos
.Col()) + nRowSize
-1 > static_cast<SCROW
>(MAXCOL
))
1434 ErrorMessage(STR_PASTE_FULL
);
1438 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1439 ::std::auto_ptr
<ScDocument
> pTransClip(new ScDocument(SCDOCMODE_CLIP
));
1440 SAL_WNODEPRECATED_DECLARATIONS_POP
1441 pClipDoc
->TransposeClip(pTransClip
.get(), nFlags
, bAsLink
);
1442 pClipDoc
= pTransClip
.release();
1443 SCCOL nTempColSize
= nColSize
;
1444 nColSize
= static_cast<SCCOL
>(nRowSize
);
1445 nRowSize
= static_cast<SCROW
>(nTempColSize
);
1448 if (!ValidCol(rCurPos
.Col()+nColSize
-1) || !ValidRow(rCurPos
.Row()+nRowSize
-1))
1450 ErrorMessage(STR_PASTE_FULL
);
1454 // Determine the first and last selected sheet numbers.
1455 SCTAB nTab1
= aMark
.GetFirstSelected();
1456 SCTAB nTab2
= aMark
.GetLastSelected();
1458 ScDocShellModificator
aModificator(*pDocSh
);
1460 // For multi-selection paste, we don't support cell duplication for larger
1461 // destination range. In case the destination is marked, we reset it to
1463 ScRange
aMarkedRange(rCurPos
.Col(), rCurPos
.Row(), nTab1
,
1464 rCurPos
.Col()+nColSize
-1, rCurPos
.Row()+nRowSize
-1, nTab2
);
1466 // Extend the marked range to account for filtered rows in the destination
1468 if (ScViewUtil::HasFiltered(aMarkedRange
, pDoc
))
1470 if (!ScViewUtil::FitToUnfilteredRows(aMarkedRange
, pDoc
, nRowSize
))
1474 bool bAskIfNotEmpty
=
1475 bAllowDialogs
&& (nFlags
& IDF_CONTENTS
) &&
1476 nFunction
== PASTE_NOFUNC
&& SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1480 ScRangeList aTestRanges
;
1481 aTestRanges
.Append(aMarkedRange
);
1482 if (!checkDestRangeForOverwrite(aTestRanges
, pDoc
, aMark
, rViewData
.GetDialogParent()))
1486 aMark
.SetMarkArea(aMarkedRange
);
1487 MarkRange(aMarkedRange
);
1489 bool bInsertCells
= (eMoveMode
!= INS_NONE
);
1492 if (!InsertCells(eMoveMode
, pDoc
->IsUndoEnabled(), true))
1496 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1497 ::std::auto_ptr
<ScDocument
> pUndoDoc
;
1498 SAL_WNODEPRECATED_DECLARATIONS_POP
1499 if (pDoc
->IsUndoEnabled())
1501 pUndoDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
1502 pUndoDoc
->InitUndoSelected(pDoc
, aMark
, false, false);
1503 pDoc
->CopyToDocument(aMarkedRange
, nUndoFlags
, false, pUndoDoc
.get(), &aMark
, true);
1506 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1507 ::std::auto_ptr
<ScDocument
> pMixDoc
;
1508 SAL_WNODEPRECATED_DECLARATIONS_POP
1509 if ( bSkipEmpty
|| nFunction
)
1511 if ( nFlags
& IDF_CONTENTS
)
1513 pMixDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
1514 pMixDoc
->InitUndoSelected(pDoc
, aMark
, false, false);
1515 pDoc
->CopyToDocument(aMarkedRange
, IDF_CONTENTS
, false, pMixDoc
.get(), &aMark
, true);
1519 /* Make draw layer and start drawing undo.
1520 - Needed before AdjustBlockHeight to track moved drawing objects.
1521 - Needed before pDoc->CopyFromClip to track inserted note caption objects.
1523 if (nFlags
& IDF_OBJECTS
)
1524 pDocSh
->MakeDrawLayer();
1525 if (pDoc
->IsUndoEnabled())
1526 pDoc
->BeginDrawUndo();
1528 sal_uInt16 nNoObjFlags
= nFlags
& ~IDF_OBJECTS
;
1529 pDoc
->CopyMultiRangeFromClip(rCurPos
, aMark
, nNoObjFlags
, pClipDoc
,
1530 true, bAsLink
, false, bSkipEmpty
);
1533 pDoc
->MixDocument(aMarkedRange
, nFunction
, bSkipEmpty
, pMixDoc
.get());
1535 AdjustBlockHeight(); // update row heights before pasting objects
1537 if (nFlags
& IDF_OBJECTS
)
1539 // Paste the drawing objects after the row heights have been updated.
1540 pDoc
->CopyMultiRangeFromClip(rCurPos
, aMark
, IDF_OBJECTS
, pClipDoc
,
1541 true, false, false, true);
1544 ScRange aTmp
= aMarkedRange
;
1545 aTmp
.aStart
.SetTab(nTab1
);
1546 aTmp
.aEnd
.SetTab(nTab1
);
1547 pDocSh
->PostPaint(aTmp
, PAINT_GRID
);
1549 if (pDoc
->IsUndoEnabled())
1551 ::svl::IUndoManager
* pUndoMgr
= pDocSh
->GetUndoManager();
1552 OUString aUndo
= ScGlobal::GetRscString(
1553 pClipDoc
->IsCutMode() ? STR_UNDO_CUT
: STR_UNDO_COPY
);
1554 pUndoMgr
->EnterListAction(aUndo
, aUndo
);
1556 ScUndoPasteOptions aOptions
; // store options for repeat
1557 aOptions
.nFunction
= nFunction
;
1558 aOptions
.bSkipEmpty
= bSkipEmpty
;
1559 aOptions
.bTranspose
= bTranspose
;
1560 aOptions
.bAsLink
= bAsLink
;
1561 aOptions
.eMoveMode
= eMoveMode
;
1563 ScUndoPaste
* pUndo
= new ScUndoPaste(pDocSh
,
1564 aMarkedRange
, aMark
, pUndoDoc
.release(), NULL
, nFlags
|nUndoFlags
, NULL
, false, &aOptions
);
1567 pUndoMgr
->AddUndoAction(new ScUndoWrapper(pUndo
), true);
1569 pUndoMgr
->AddUndoAction(pUndo
, false);
1571 pUndoMgr
->LeaveListAction();
1575 aModificator
.SetDocumentModified();
1576 PostPasteFromClip(aMarkedRange
, aMark
);
1580 bool ScViewFunc::PasteFromClipToMultiRanges(
1581 sal_uInt16 nFlags
, ScDocument
* pClipDoc
, sal_uInt16 nFunction
,
1582 bool bSkipEmpty
, bool bTranspose
, bool bAsLink
, bool bAllowDialogs
,
1583 InsCellCmd eMoveMode
, sal_uInt16 nUndoFlags
)
1587 // We don't allow transpose for this yet.
1588 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
1592 if (eMoveMode
!= INS_NONE
)
1594 // We don't allow insertion mode either. Too complicated.
1595 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
1599 ScViewData
& rViewData
= *GetViewData();
1600 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
1601 if (rClipParam
.mbCutMode
)
1603 // No cut and paste with this, please.
1604 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
1608 const ScAddress
& rCurPos
= rViewData
.GetCurPos();
1609 ScDocument
* pDoc
= rViewData
.GetDocument();
1611 ScRange aSrcRange
= rClipParam
.getWholeRange();
1612 SCROW nRowSize
= aSrcRange
.aEnd
.Row() - aSrcRange
.aStart
.Row() + 1;
1613 SCCOL nColSize
= aSrcRange
.aEnd
.Col() - aSrcRange
.aStart
.Col() + 1;
1615 if (!ValidCol(rCurPos
.Col()+nColSize
-1) || !ValidRow(rCurPos
.Row()+nRowSize
-1))
1617 ErrorMessage(STR_PASTE_FULL
);
1621 ScMarkData
aMark(rViewData
.GetMarkData());
1623 ScRangeList aRanges
;
1624 aMark
.MarkToSimple();
1625 aMark
.FillRangeListWithMarks(&aRanges
, false);
1626 if (!ScClipUtil::CheckDestRanges(pDoc
, nColSize
, nRowSize
, aMark
, aRanges
))
1628 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
1632 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
1634 ScDocShellModificator
aModificator(*pDocSh
);
1636 bool bAskIfNotEmpty
=
1637 bAllowDialogs
&& (nFlags
& IDF_CONTENTS
) &&
1638 nFunction
== PASTE_NOFUNC
&& SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1642 if (!checkDestRangeForOverwrite(aRanges
, pDoc
, aMark
, rViewData
.GetDialogParent()))
1646 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1647 std::auto_ptr
<ScDocument
> pUndoDoc
;
1648 SAL_WNODEPRECATED_DECLARATIONS_POP
1649 if (pDoc
->IsUndoEnabled())
1651 pUndoDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
1652 pUndoDoc
->InitUndoSelected(pDoc
, aMark
, false, false);
1653 for (size_t i
= 0, n
= aRanges
.size(); i
< n
; ++i
)
1655 pDoc
->CopyToDocument(
1656 *aRanges
[i
], nUndoFlags
, false, pUndoDoc
.get(), &aMark
, true);
1660 boost::scoped_ptr
<ScDocument
> pMixDoc
;
1661 if (bSkipEmpty
|| nFunction
)
1663 if (nFlags
& IDF_CONTENTS
)
1665 pMixDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
1666 pMixDoc
->InitUndoSelected(pDoc
, aMark
, false, false);
1667 for (size_t i
= 0, n
= aRanges
.size(); i
< n
; ++i
)
1669 pDoc
->CopyToDocument(
1670 *aRanges
[i
], IDF_CONTENTS
, false, pMixDoc
.get(), &aMark
, true);
1675 if (nFlags
& IDF_OBJECTS
)
1676 pDocSh
->MakeDrawLayer();
1677 if (pDoc
->IsUndoEnabled())
1678 pDoc
->BeginDrawUndo();
1680 // First, paste everything but the drawing objects.
1681 for (size_t i
= 0, n
= aRanges
.size(); i
< n
; ++i
)
1684 *aRanges
[i
], aMark
, (nFlags
& ~IDF_OBJECTS
), NULL
, pClipDoc
,
1685 false, false, true, bSkipEmpty
, NULL
);
1690 for (size_t i
= 0, n
= aRanges
.size(); i
< n
; ++i
)
1691 pDoc
->MixDocument(*aRanges
[i
], nFunction
, bSkipEmpty
, pMixDoc
.get());
1694 AdjustBlockHeight(); // update row heights before pasting objects
1696 // Then paste the objects.
1697 if (nFlags
& IDF_OBJECTS
)
1699 for (size_t i
= 0, n
= aRanges
.size(); i
< n
; ++i
)
1702 *aRanges
[i
], aMark
, IDF_OBJECTS
, NULL
, pClipDoc
,
1703 false, false, true, bSkipEmpty
, NULL
);
1707 // Refresh the range that includes all pasted ranges. We only need to
1708 // refresh the current sheet.
1709 pDocSh
->PostPaint(aRanges
, PAINT_GRID
);
1711 if (pDoc
->IsUndoEnabled())
1713 svl::IUndoManager
* pUndoMgr
= pDocSh
->GetUndoManager();
1714 OUString aUndo
= ScGlobal::GetRscString(
1715 pClipDoc
->IsCutMode() ? STR_UNDO_CUT
: STR_UNDO_COPY
);
1716 pUndoMgr
->EnterListAction(aUndo
, aUndo
);
1718 ScUndoPasteOptions aOptions
; // store options for repeat
1719 aOptions
.nFunction
= nFunction
;
1720 aOptions
.bSkipEmpty
= bSkipEmpty
;
1721 aOptions
.bTranspose
= bTranspose
;
1722 aOptions
.bAsLink
= bAsLink
;
1723 aOptions
.eMoveMode
= eMoveMode
;
1725 ScUndoPaste
* pUndo
= new ScUndoPaste(
1726 pDocSh
, aRanges
, aMark
, pUndoDoc
.release(), NULL
, nFlags
|nUndoFlags
, NULL
, false, &aOptions
);
1728 pUndoMgr
->AddUndoAction(pUndo
, false);
1729 pUndoMgr
->LeaveListAction();
1733 aModificator
.SetDocumentModified();
1734 PostPasteFromClip(aRanges
, aMark
);
1739 void ScViewFunc::PostPasteFromClip(const ScRangeList
& rPasteRanges
, const ScMarkData
& rMark
)
1741 ScViewData
* pViewData
= GetViewData();
1742 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
1743 pDocSh
->UpdateOle(pViewData
);
1747 ScModelObj
* pModelObj
= HelperNotifyChanges::getMustPropagateChangesModel(*pDocSh
);
1751 ScRangeList aChangeRanges
;
1752 for (size_t i
= 0, n
= rPasteRanges
.size(); i
< n
; ++i
)
1754 const ScRange
& r
= *rPasteRanges
[i
];
1755 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1756 for (; itr
!= itrEnd
; ++itr
)
1758 ScRange
aChangeRange(r
);
1759 aChangeRange
.aStart
.SetTab(*itr
);
1760 aChangeRange
.aEnd
.SetTab(*itr
);
1761 aChangeRanges
.Append(aChangeRange
);
1764 HelperNotifyChanges::Notify(*pModelObj
, aChangeRanges
);
1767 // D R A G A N D D R O P
1769 // innerhalb des Dokuments
1771 bool ScViewFunc::MoveBlockTo( const ScRange
& rSource
, const ScAddress
& rDestPos
,
1772 bool bCut
, bool bRecord
, bool bPaint
, bool bApi
)
1774 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1775 HideAllCursors(); // wegen zusammengefassten
1777 bool bSuccess
= true;
1778 SCTAB nDestTab
= rDestPos
.Tab();
1779 const ScMarkData
& rMark
= GetViewData()->GetMarkData();
1780 if ( rSource
.aStart
.Tab() == nDestTab
&& rSource
.aEnd
.Tab() == nDestTab
&& rMark
.GetSelectCount() > 1 )
1782 // moving within one table and several tables selected -> apply to all selected tables
1786 OUString aUndo
= ScGlobal::GetRscString( bCut
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
1787 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
1790 // collect ranges of consecutive selected tables
1792 ScRange aLocalSource
= rSource
;
1793 ScAddress aLocalDest
= rDestPos
;
1794 SCTAB nTabCount
= pDocSh
->GetDocument()->GetTableCount();
1795 SCTAB nStartTab
= 0;
1796 while ( nStartTab
< nTabCount
&& bSuccess
)
1798 while ( nStartTab
< nTabCount
&& !rMark
.GetTableSelect(nStartTab
) )
1800 if ( nStartTab
< nTabCount
)
1802 SCTAB nEndTab
= nStartTab
;
1803 while ( nEndTab
+1 < nTabCount
&& rMark
.GetTableSelect(nEndTab
+1) )
1806 aLocalSource
.aStart
.SetTab( nStartTab
);
1807 aLocalSource
.aEnd
.SetTab( nEndTab
);
1808 aLocalDest
.SetTab( nStartTab
);
1810 bSuccess
= pDocSh
->GetDocFunc().MoveBlock(
1811 aLocalSource
, aLocalDest
, bCut
, bRecord
, bPaint
, bApi
);
1813 nStartTab
= nEndTab
+ 1;
1818 pDocSh
->GetUndoManager()->LeaveListAction();
1822 // move the block as specified
1823 bSuccess
= pDocSh
->GetDocFunc().MoveBlock(
1824 rSource
, rDestPos
, bCut
, bRecord
, bPaint
, bApi
);
1830 // Zielbereich markieren
1832 rDestPos
.Col() + rSource
.aEnd
.Col() - rSource
.aStart
.Col(),
1833 rDestPos
.Row() + rSource
.aEnd
.Row() - rSource
.aStart
.Row(),
1836 bool bIncludeFiltered
= bCut
;
1837 if ( !bIncludeFiltered
)
1839 // find number of non-filtered rows
1840 SCROW nPastedCount
= pDocSh
->GetDocument()->CountNonFilteredRows(
1841 rSource
.aStart
.Row(), rSource
.aEnd
.Row(), rSource
.aStart
.Tab());
1843 if ( nPastedCount
== 0 )
1845 aDestEnd
.SetRow( rDestPos
.Row() + nPastedCount
- 1 );
1848 MarkRange( ScRange( rDestPos
, aDestEnd
), false ); //! sal_False ???
1850 pDocSh
->UpdateOle(GetViewData());
1857 // Link innerhalb des Dokuments
1859 bool ScViewFunc::LinkBlock( const ScRange
& rSource
, const ScAddress
& rDestPos
, bool bApi
)
1861 // Test auf Ueberlappung
1863 if ( rSource
.aStart
.Tab() == rDestPos
.Tab() )
1865 SCCOL nDestEndCol
= rDestPos
.Col() + ( rSource
.aEnd
.Col() - rSource
.aStart
.Col() );
1866 SCROW nDestEndRow
= rDestPos
.Row() + ( rSource
.aEnd
.Row() - rSource
.aStart
.Row() );
1868 if ( rSource
.aStart
.Col() <= nDestEndCol
&& rDestPos
.Col() <= rSource
.aEnd
.Col() &&
1869 rSource
.aStart
.Row() <= nDestEndRow
&& rDestPos
.Row() <= rSource
.aEnd
.Row() )
1872 ErrorMessage( STR_ERR_LINKOVERLAP
);
1877 // Ausfuehren per Paste
1879 ScDocument
* pDoc
= GetViewData()->GetDocument();
1880 boost::scoped_ptr
<ScDocument
> pClipDoc(new ScDocument( SCDOCMODE_CLIP
));
1881 pDoc
->CopyTabToClip( rSource
.aStart
.Col(), rSource
.aStart
.Row(),
1882 rSource
.aEnd
.Col(), rSource
.aEnd
.Row(),
1883 rSource
.aStart
.Tab(), pClipDoc
.get() );
1885 // Zielbereich markieren (Cursor setzen, keine Markierung)
1887 if ( GetViewData()->GetTabNo() != rDestPos
.Tab() )
1888 SetTabNo( rDestPos
.Tab() );
1890 MoveCursorAbs( rDestPos
.Col(), rDestPos
.Row(), SC_FOLLOW_NONE
, false, false );
1894 PasteFromClip( IDF_ALL
, pClipDoc
.get(), PASTE_NOFUNC
, false, false, true ); // als Link
1899 void ScViewFunc::DataFormPutData( SCROW nCurrentRow
,
1900 SCROW nStartRow
, SCCOL nStartCol
,
1901 SCROW nEndRow
, SCCOL nEndCol
,
1902 boost::ptr_vector
<boost::nullable
<Edit
> >& aEdits
,
1903 sal_uInt16 aColLength
)
1905 ScDocument
* pDoc
= GetViewData()->GetDocument();
1906 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1907 ScMarkData
& rMark
= GetViewData()->GetMarkData();
1908 ScDocShellModificator
aModificator( *pDocSh
);
1909 ::svl::IUndoManager
* pUndoMgr
= pDocSh
->GetUndoManager();
1912 const bool bRecord( pDoc
->IsUndoEnabled());
1913 ScDocument
* pUndoDoc
= NULL
;
1914 ScDocument
* pRedoDoc
= NULL
;
1915 ScRefUndoData
* pUndoData
= NULL
;
1916 SCTAB nTab
= GetViewData()->GetTabNo();
1917 SCTAB nStartTab
= nTab
;
1918 SCTAB nEndTab
= nTab
;
1921 ScChangeTrack
* pChangeTrack
= pDoc
->GetChangeTrack();
1923 pChangeTrack
->ResetLastCut(); // kein CutMode mehr
1925 ScRange
aUserRange( nStartCol
, nCurrentRow
, nStartTab
, nEndCol
, nCurrentRow
, nEndTab
);
1926 bool bColInfo
= ( nStartRow
==0 && nEndRow
==MAXROW
);
1927 bool bRowInfo
= ( nStartCol
==0 && nEndCol
==MAXCOL
);
1928 SCCOL nUndoEndCol
= nStartCol
+aColLength
-1;
1929 SCROW nUndoEndRow
= nCurrentRow
;
1930 sal_uInt16 nUndoFlags
= IDF_NONE
;
1934 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1935 pUndoDoc
->InitUndoSelected( pDoc
, rMark
, bColInfo
, bRowInfo
);
1936 pDoc
->CopyToDocument( aUserRange
, 1 , false , pUndoDoc
);
1938 sal_uInt16 nExtFlags
= 0;
1939 pDocSh
->UpdatePaintExt( nExtFlags
, nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
); // content before the change
1940 pDoc
->BeginDrawUndo();
1942 for(sal_uInt16 i
= 0; i
< aColLength
; i
++)
1944 if (!aEdits
.is_null(i
))
1946 OUString aFieldName
=aEdits
[i
].GetText();
1947 pDoc
->SetString( nStartCol
+ i
, nCurrentRow
, nTab
, aFieldName
);
1950 pDocSh
->UpdatePaintExt( nExtFlags
, nStartCol
, nCurrentRow
, nStartTab
, nEndCol
, nCurrentRow
, nEndTab
); // content after the change
1951 SfxUndoAction
* pUndo
= new ScUndoDataForm( pDocSh
,
1952 nStartCol
, nCurrentRow
, nStartTab
,
1953 nUndoEndCol
, nUndoEndRow
, nEndTab
, rMark
,
1954 pUndoDoc
, pRedoDoc
, nUndoFlags
,
1955 pUndoData
, NULL
, NULL
, NULL
,
1956 false ); // FALSE = Redo data not yet copied
1957 pUndoMgr
->AddUndoAction( new ScUndoWrapper( pUndo
), true );
1959 sal_uInt16 nPaint
= PAINT_GRID
;
1962 nPaint
|= PAINT_TOP
;
1963 nUndoEndCol
= MAXCOL
; // nur zum Zeichnen !
1967 nPaint
|= PAINT_LEFT
;
1968 nUndoEndRow
= MAXROW
; // nur zum Zeichnen !
1972 ScRange(nStartCol
, nCurrentRow
, nStartTab
, nUndoEndCol
, nUndoEndRow
, nEndTab
),
1974 pDocSh
->UpdateOle(GetViewData());
1979 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */