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 .
22 #include "scitems.hxx"
23 #include <svx/svdetc.hxx>
24 #include <svx/svditer.hxx>
25 #include <svx/svdoole2.hxx>
26 #include <svx/svdpage.hxx>
27 #include <sfx2/dispatch.hxx>
28 #include <sfx2/docfile.hxx>
29 #include <svl/stritem.hxx>
30 #include <svl/ptitem.hxx>
31 #include <svl/urlbmk.hxx>
32 #include <comphelper/classids.hxx>
33 #include <sot/formats.hxx>
34 #include <vcl/graph.hxx>
35 #include <vcl/virdev.hxx>
36 #include <vcl/msgbox.hxx>
37 #include <tools/urlobj.hxx>
38 #include <sot/exchange.hxx>
42 #include "patattr.hxx"
43 #include "dociter.hxx"
44 #include "viewfunc.hxx"
45 #include "tabvwsh.hxx"
47 #include "docfunc.hxx"
48 #include "undoblk.hxx"
49 #include "refundo.hxx"
50 #include "globstr.hrc"
52 #include "transobj.hxx"
53 #include "drwtrans.hxx"
54 #include "rangenam.hxx"
56 #include "impex.hxx" // Sylk-ID fuer CB
57 #include "chgtrack.hxx"
58 #include "waitoff.hxx"
61 #include "inputopt.hxx"
62 #include "warnbox.hxx"
63 #include "drwlayer.hxx"
64 #include "editable.hxx"
66 #include "clipparam.hxx"
67 #include "undodat.hxx"
68 #include "drawview.hxx"
69 #include "cliputil.hxx"
71 using namespace com::sun::star
;
73 // STATIC DATA ---------------------------------------------------------------
76 //============================================================================
78 // GlobalName der Writer-DocShell kommt jetzt aus comphelper/classids.hxx
80 //----------------------------------------------------------------------------
83 void ScViewFunc::CutToClip( ScDocument
* pClipDoc
, sal_Bool bIncludeObjects
)
87 ScEditableTester
aTester( this );
88 if (!aTester
.IsEditable()) // selection editable?
90 ErrorMessage( aTester
.GetMessageId() );
94 ScRange aRange
; // zu loeschender Bereich
95 if ( GetViewData()->GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
97 ScDocument
* pDoc
= GetViewData()->GetDocument();
98 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
99 ScMarkData
& rMark
= GetViewData()->GetMarkData();
100 const sal_Bool
bRecord(pDoc
->IsUndoEnabled()); // Undo/Redo
102 ScDocShellModificator
aModificator( *pDocSh
);
104 if ( !rMark
.IsMarked() && !rMark
.IsMultiMarked() ) // mark the range if not marked yet
108 rMark
.SetMarkArea( aRange
);
112 CopyToClip( pClipDoc
, sal_True
, false, bIncludeObjects
); // Ab ins Clipboard
114 ScAddress
aOldEnd( aRange
.aEnd
); // Zusammengefasste Zellen im Bereich?
115 pDoc
->ExtendMerge( aRange
, sal_True
);
117 ScDocument
* pUndoDoc
= NULL
;
120 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
121 pUndoDoc
->InitUndoSelected( pDoc
, rMark
);
122 // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
123 ScRange aCopyRange
= aRange
;
124 aCopyRange
.aStart
.SetTab(0);
125 aCopyRange
.aEnd
.SetTab(pDoc
->GetTableCount()-1);
126 pDoc
->CopyToDocument( aCopyRange
, (IDF_ALL
& ~IDF_OBJECTS
) | IDF_NOCAPTIONS
, false, pUndoDoc
);
127 pDoc
->BeginDrawUndo();
130 sal_uInt16 nExtFlags
= 0;
131 pDocSh
->UpdatePaintExt( nExtFlags
, aRange
);
134 pDoc
->DeleteSelection( IDF_ALL
, rMark
);
135 if ( bIncludeObjects
)
136 pDoc
->DeleteObjectsInSelection( rMark
);
137 rMark
.MarkToSimple();
139 if ( !AdjustRowHeight( aRange
.aStart
.Row(), aRange
.aEnd
.Row() ) )
140 pDocSh
->PostPaint( aRange
, PAINT_GRID
, nExtFlags
);
142 if ( bRecord
) // erst jetzt ist Draw-Undo verfuegbar
143 pDocSh
->GetUndoManager()->AddUndoAction(
144 new ScUndoCut( pDocSh
, aRange
, aOldEnd
, rMark
, pUndoDoc
) );
146 aModificator
.SetDocumentModified();
147 pDocSh
->UpdateOle(GetViewData());
149 CellContentChanged();
152 ErrorMessage( STR_NOMULTISELECT
);
156 //----------------------------------------------------------------------------
159 sal_Bool
ScViewFunc::CopyToClip( ScDocument
* pClipDoc
, sal_Bool bCut
, sal_Bool bApi
, sal_Bool bIncludeObjects
, sal_Bool bStopEdit
)
162 ScMarkType eMarkType
= GetViewData()->GetSimpleArea( aRange
);
163 ScMarkData
& rMark
= GetViewData()->GetMarkData();
164 sal_Bool bDone
= sal_False
;
166 if ( eMarkType
== SC_MARK_SIMPLE
|| eMarkType
== SC_MARK_SIMPLE_FILTERED
)
168 ScRangeList aRangeList
;
169 aRangeList
.Append( aRange
);
170 bDone
= CopyToClip( pClipDoc
, aRangeList
, bCut
, bApi
, bIncludeObjects
, bStopEdit
, sal_False
);
172 else if (eMarkType
== SC_MARK_MULTI
)
174 ScRangeList aRangeList
;
175 rMark
.MarkToSimple();
176 rMark
.FillRangeListWithMarks(&aRangeList
, false);
177 bDone
= CopyToClip( pClipDoc
, aRangeList
, bCut
, bApi
, bIncludeObjects
, bStopEdit
, sal_False
);
182 ErrorMessage(STR_NOMULTISELECT
);
188 // Copy the content of the Range into clipboard.
189 sal_Bool
ScViewFunc::CopyToClip( ScDocument
* pClipDoc
, const ScRangeList
& rRanges
, sal_Bool bCut
, sal_Bool bApi
, sal_Bool bIncludeObjects
, sal_Bool bStopEdit
, sal_Bool bUseRangeForVBA
)
191 if ( rRanges
.empty() )
193 sal_Bool bDone
= false;
197 ScRange aRange
= *rRanges
[0];
198 ScClipParam
aClipParam( aRange
, bCut
);
199 aClipParam
.maRanges
= rRanges
;
201 ScDocument
* pDoc
= GetViewData()->GetDocument();
202 ScMarkData
& rMark
= GetViewData()->GetMarkData();
204 if ( !aClipParam
.isMultiRange() )
206 if ( pDoc
&& ( !pDoc
->HasSelectedBlockMatrixFragment( aRange
.aStart
.Col(), aRange
.aStart
.Row(), aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), rMark
) ) )
208 sal_Bool bSysClip
= false;
209 if ( !pClipDoc
) // no clip doc specified
211 // Create one (deleted by ScTransferObj).
212 pClipDoc
= new ScDocument( SCDOCMODE_CLIP
);
213 bSysClip
= sal_True
; // and copy into system
217 ScChangeTrack
* pChangeTrack
= pDoc
->GetChangeTrack();
219 pChangeTrack
->ResetLastCut();
222 if ( bSysClip
&& bIncludeObjects
)
224 sal_Bool bAnyOle
= pDoc
->HasOLEObjectsInArea( aRange
);
225 // Update ScGlobal::pDrawClipDocShellRef.
226 ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle
) );
229 if ( !bUseRangeForVBA
)
230 // is this necessary?, will setting the doc id upset the
231 // following paste operation with range? would be nicer to just set this always
232 // and lose the 'if' above
233 aClipParam
.setSourceDocID( pDoc
->GetDocumentID() );
235 pDoc
->CopyToClip( aClipParam
, pClipDoc
, &rMark
, false, false, bIncludeObjects
, true, bUseRangeForVBA
);
236 if ( !bUseRangeForVBA
&& pDoc
&& pClipDoc
)
238 ScDrawLayer
* pDrawLayer
= pClipDoc
->GetDrawLayer();
241 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
242 ScRangeListVector
& rRangesVector
= rClipParam
.maProtectedChartRangesVector
;
243 SCTAB nTabCount
= pClipDoc
->GetTableCount();
244 for ( SCTAB nTab
= 0; nTab
< nTabCount
; ++nTab
)
246 SdrPage
* pPage
= pDrawLayer
->GetPage( static_cast< sal_uInt16
>( nTab
) );
249 ScChartHelper::FillProtectedChartRangesVector( rRangesVector
, pDoc
, pPage
);
257 ScDrawLayer::SetGlobalDrawPersist(NULL
);
258 ScGlobal::SetClipDocName( pDoc
->GetDocumentShell()->GetTitle( SFX_TITLE_FULLNAME
) );
260 pClipDoc
->ExtendMerge( aRange
, true );
264 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
265 TransferableObjectDescriptor aObjDesc
;
266 pDocSh
->FillTransferableObjectDescriptor( aObjDesc
);
267 aObjDesc
.maDisplayName
= pDocSh
->GetMedium()->GetURLObject().GetURLNoPass();
268 // maSize is set in ScTransferObj ctor
270 ScTransferObj
* pTransferObj
= new ScTransferObj( pClipDoc
, aObjDesc
);
271 uno::Reference
<datatransfer::XTransferable
> xTransferable( pTransferObj
);
272 if ( ScGlobal::pDrawClipDocShellRef
)
274 SfxObjectShellRef
aPersistRef( &(*ScGlobal::pDrawClipDocShellRef
) );
275 pTransferObj
->SetDrawPersist( aPersistRef
);// keep persist for ole objects alive
278 pTransferObj
->CopyToClipboard( GetActiveWin() );
279 SC_MOD()->SetClipObject( pTransferObj
, NULL
);
287 bool bSuccess
= false;
288 aClipParam
.mbCutMode
= false;
293 // We con't support cutting of multi-selections.
297 // TODO: What's this for?
300 SAL_WNODEPRECATED_DECLARATIONS_PUSH
301 ::std::auto_ptr
<ScDocument
> pDocClip(new ScDocument(SCDOCMODE_CLIP
));
302 SAL_WNODEPRECATED_DECLARATIONS_POP
304 // Check for geometrical feasibility of the ranges.
305 bool bValidRanges
= true;
306 ScRange
* p
= aClipParam
.maRanges
.front();
307 SCCOL nPrevColDelta
= 0;
308 SCROW nPrevRowDelta
= 0;
309 SCCOL nPrevCol
= p
->aStart
.Col();
310 SCROW nPrevRow
= p
->aStart
.Row();
311 SCCOL nPrevColSize
= p
->aEnd
.Col() - p
->aStart
.Col() + 1;
312 SCROW nPrevRowSize
= p
->aEnd
.Row() - p
->aStart
.Row() + 1;
313 for ( size_t i
= 1; i
< aClipParam
.maRanges
.size(); ++i
)
315 p
= aClipParam
.maRanges
[i
];
316 if ( pDoc
->HasSelectedBlockMatrixFragment(
317 p
->aStart
.Col(), p
->aStart
.Row(), p
->aEnd
.Col(), p
->aEnd
.Row(), rMark
) )
320 ErrorMessage(STR_MATRIXFRAGMENTERR
);
324 SCCOL nColDelta
= p
->aStart
.Col() - nPrevCol
;
325 SCROW nRowDelta
= p
->aStart
.Row() - nPrevRow
;
327 if ((nColDelta
&& nRowDelta
) || (nPrevColDelta
&& nRowDelta
) || (nPrevRowDelta
&& nColDelta
))
329 bValidRanges
= false;
333 if (aClipParam
.meDirection
== ScClipParam::Unspecified
)
336 aClipParam
.meDirection
= ScClipParam::Column
;
338 aClipParam
.meDirection
= ScClipParam::Row
;
341 SCCOL nColSize
= p
->aEnd
.Col() - p
->aStart
.Col() + 1;
342 SCROW nRowSize
= p
->aEnd
.Row() - p
->aStart
.Row() + 1;
344 if (aClipParam
.meDirection
== ScClipParam::Column
&& nRowSize
!= nPrevRowSize
)
346 // column-oriented ranges must have identical row size.
347 bValidRanges
= false;
350 if (aClipParam
.meDirection
== ScClipParam::Row
&& nColSize
!= nPrevColSize
)
352 // likewise, row-oriented ranges must have identical
354 bValidRanges
= false;
358 nPrevCol
= p
->aStart
.Col();
359 nPrevRow
= p
->aStart
.Row();
360 nPrevColDelta
= nColDelta
;
361 nPrevRowDelta
= nRowDelta
;
362 nPrevColSize
= nColSize
;
363 nPrevRowSize
= nRowSize
;
367 pDoc
->CopyToClip(aClipParam
, pDocClip
.get(), &rMark
, false, false, bIncludeObjects
, true, bUseRangeForVBA
);
369 ScChangeTrack
* pChangeTrack
= pDoc
->GetChangeTrack();
371 pChangeTrack
->ResetLastCut(); // kein CutMode mehr
374 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
375 TransferableObjectDescriptor aObjDesc
;
376 pDocSh
->FillTransferableObjectDescriptor( aObjDesc
);
377 aObjDesc
.maDisplayName
= pDocSh
->GetMedium()->GetURLObject().GetURLNoPass();
378 // maSize is set in ScTransferObj ctor
380 ScTransferObj
* pTransferObj
= new ScTransferObj( pDocClip
.release(), aObjDesc
);
381 uno::Reference
<datatransfer::XTransferable
> xTransferable( pTransferObj
);
383 if ( ScGlobal::pDrawClipDocShellRef
)
385 SfxObjectShellRef
aPersistRef( &(*ScGlobal::pDrawClipDocShellRef
) );
386 pTransferObj
->SetDrawPersist( aPersistRef
); // keep persist for ole objects alive
389 pTransferObj
->CopyToClipboard( GetActiveWin() ); // system clipboard
390 SC_MOD()->SetClipObject( pTransferObj
, NULL
); // internal clipboard
397 if (!bSuccess
&& !bApi
)
398 ErrorMessage(STR_NOMULTISELECT
);
406 ScTransferObj
* ScViewFunc::CopyToTransferable()
409 if ( GetViewData()->GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
411 ScDocument
* pDoc
= GetViewData()->GetDocument();
412 ScMarkData
& rMark
= GetViewData()->GetMarkData();
413 if ( !pDoc
->HasSelectedBlockMatrixFragment(
414 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
415 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(),
418 ScDocument
*pClipDoc
= new ScDocument( SCDOCMODE_CLIP
); // create one (deleted by ScTransferObj)
420 sal_Bool bAnyOle
= pDoc
->HasOLEObjectsInArea( aRange
, &rMark
);
421 ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle
) );
423 ScClipParam
aClipParam(aRange
, false);
424 pDoc
->CopyToClip(aClipParam
, pClipDoc
, &rMark
, false, false, true);
426 ScDrawLayer::SetGlobalDrawPersist(NULL
);
427 pClipDoc
->ExtendMerge( aRange
, sal_True
);
429 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
430 TransferableObjectDescriptor aObjDesc
;
431 pDocSh
->FillTransferableObjectDescriptor( aObjDesc
);
432 aObjDesc
.maDisplayName
= pDocSh
->GetMedium()->GetURLObject().GetURLNoPass();
433 ScTransferObj
* pTransferObj
= new ScTransferObj( pClipDoc
, aObjDesc
);
441 //----------------------------------------------------------------------------
444 void ScViewFunc::PasteDraw()
446 ScViewData
* pViewData
= GetViewData();
447 SCCOL nPosX
= pViewData
->GetCurX();
448 SCROW nPosY
= pViewData
->GetCurY();
449 Window
* pWin
= GetActiveWin();
450 Point aPos
= pWin
->PixelToLogic( pViewData
->GetScrPos( nPosX
, nPosY
,
451 pViewData
->GetActivePart() ) );
452 ScDrawTransferObj
* pDrawClip
= ScDrawTransferObj::GetOwnClipboard( pWin
);
454 PasteDraw( aPos
, pDrawClip
->GetModel(), false,
455 pDrawClip
->GetSourceDocID() == pViewData
->GetDocument()->GetDocumentID() );
458 void ScViewFunc::PasteFromSystem()
462 Window
* pWin
= GetActiveWin();
463 ScTransferObj
* pOwnClip
= ScTransferObj::GetOwnClipboard( pWin
);
464 ScDrawTransferObj
* pDrawClip
= ScDrawTransferObj::GetOwnClipboard( pWin
);
468 // keep a reference in case the clipboard is changed during PasteFromClip
469 uno::Reference
<datatransfer::XTransferable
> aOwnClipRef( pOwnClip
);
470 PasteFromClip( IDF_ALL
, pOwnClip
->GetDocument(),
471 PASTE_NOFUNC
, false, false, false, INS_NONE
, IDF_NONE
,
472 sal_True
); // allow warning dialog
478 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin
) );
481 sal_uLong nBiff8
= SotExchange::RegisterFormatName(OUString("Biff8"));
482 sal_uLong nBiff5
= SotExchange::RegisterFormatName(OUString("Biff5"));
484 // als erstes SvDraw-Model, dann Grafik
485 // (Grafik darf nur bei einzelner Grafik drinstehen)
487 if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_DRAWING
))
489 // special case for tables from drawing
490 if( aDataHelper
.HasFormat( SOT_FORMAT_RTF
) )
492 PasteFromSystem( FORMAT_RTF
);
496 PasteFromSystem( SOT_FORMATSTR_ID_DRAWING
);
499 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SVXB
))
500 PasteFromSystem( SOT_FORMATSTR_ID_SVXB
);
501 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE
))
503 // If it's a Writer object, insert RTF instead of OLE
505 // Else, if the class id is all-zero, and SYLK is available,
506 // it probably is spreadsheet cells that have been put
507 // on the clipboard by OOo, so use the SYLK. (fdo#31077)
509 sal_Bool bDoRtf
= false;
510 TransferableObjectDescriptor aObjDesc
;
511 if( aDataHelper
.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
, aObjDesc
) )
513 bDoRtf
= ( ( aObjDesc
.maClassName
== SvGlobalName( SO3_SW_CLASSID
) ||
514 aObjDesc
.maClassName
== SvGlobalName( SO3_SWWEB_CLASSID
) )
515 && aDataHelper
.HasFormat( SOT_FORMAT_RTF
) );
518 PasteFromSystem( FORMAT_RTF
);
519 else if ( aObjDesc
.maClassName
== SvGlobalName( 0,0,0,0,0,0,0,0,0,0,0 )
520 && aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SYLK
))
521 PasteFromSystem( SOT_FORMATSTR_ID_SYLK
);
523 PasteFromSystem( SOT_FORMATSTR_ID_EMBED_SOURCE
);
525 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE
))
526 PasteFromSystem( SOT_FORMATSTR_ID_LINK_SOURCE
);
527 // the following format can not affect scenario from #89579#
528 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
))
529 PasteFromSystem( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
);
530 // FORMAT_PRIVATE no longer here (can't work if pOwnClip is NULL)
531 else if (aDataHelper
.HasFormat(nBiff8
)) // before xxx_OLE formats
532 PasteFromSystem(nBiff8
);
533 else if (aDataHelper
.HasFormat(nBiff5
))
534 PasteFromSystem(nBiff5
);
535 else if (aDataHelper
.HasFormat(FORMAT_RTF
))
536 PasteFromSystem(FORMAT_RTF
);
537 else if (aDataHelper
.HasFormat(SOT_FORMATSTR_ID_HTML
))
538 PasteFromSystem(SOT_FORMATSTR_ID_HTML
);
539 else if (aDataHelper
.HasFormat(SOT_FORMATSTR_ID_HTML_SIMPLE
))
540 PasteFromSystem(SOT_FORMATSTR_ID_HTML_SIMPLE
);
541 else if (aDataHelper
.HasFormat(SOT_FORMATSTR_ID_SYLK
))
542 PasteFromSystem(SOT_FORMATSTR_ID_SYLK
);
543 else if (aDataHelper
.HasFormat(FORMAT_STRING
))
544 PasteFromSystem(FORMAT_STRING
);
545 else if (aDataHelper
.HasFormat(FORMAT_GDIMETAFILE
))
546 PasteFromSystem(FORMAT_GDIMETAFILE
);
547 else if (aDataHelper
.HasFormat(FORMAT_BITMAP
))
548 PasteFromSystem(FORMAT_BITMAP
);
549 // xxx_OLE formats come last, like in SotExchange tables
550 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
))
551 PasteFromSystem( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
);
552 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
))
553 PasteFromSystem( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
);
556 // keine Fehlermeldung, weil SID_PASTE in der idl das FastCall-Flag hat,
557 // also auch gerufen wird, wenn nichts im Clipboard steht (#42531#)
560 void ScViewFunc::PasteFromTransferable( const uno::Reference
<datatransfer::XTransferable
>& rxTransferable
)
562 ScTransferObj
*pOwnClip
=0;
563 ScDrawTransferObj
*pDrawClip
=0;
564 uno::Reference
<lang::XUnoTunnel
> xTunnel( rxTransferable
, uno::UNO_QUERY
);
567 sal_Int64 nHandle
= xTunnel
->getSomething( ScTransferObj::getUnoTunnelId() );
569 pOwnClip
= (ScTransferObj
*) (sal_IntPtr
) nHandle
;
572 nHandle
= xTunnel
->getSomething( ScDrawTransferObj::getUnoTunnelId() );
574 pDrawClip
= (ScDrawTransferObj
*) (sal_IntPtr
) nHandle
;
580 PasteFromClip( IDF_ALL
, pOwnClip
->GetDocument(),
581 PASTE_NOFUNC
, false, false, false, INS_NONE
, IDF_NONE
,
582 sal_True
); // allow warning dialog
586 ScViewData
* pViewData
= GetViewData();
587 SCCOL nPosX
= pViewData
->GetCurX();
588 SCROW nPosY
= pViewData
->GetCurY();
589 Window
* pWin
= GetActiveWin();
590 Point aPos
= pWin
->PixelToLogic( pViewData
->GetScrPos( nPosX
, nPosY
, pViewData
->GetActivePart() ) );
591 PasteDraw( aPos
, pDrawClip
->GetModel(), false, pDrawClip
->GetSourceDocID() == pViewData
->GetDocument()->GetDocumentID() );
595 TransferableDataHelper
aDataHelper( rxTransferable
);
597 sal_uLong nBiff8
= SotExchange::RegisterFormatName(OUString("Biff8"));
598 sal_uLong nBiff5
= SotExchange::RegisterFormatName(OUString("Biff5"));
599 sal_uLong nFormatId
= 0;
600 // als erstes SvDraw-Model, dann Grafik
601 // (Grafik darf nur bei einzelner Grafik drinstehen)
603 if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_DRAWING
))
604 nFormatId
= SOT_FORMATSTR_ID_DRAWING
;
605 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SVXB
))
606 nFormatId
= SOT_FORMATSTR_ID_SVXB
;
607 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE
))
609 // If it's a Writer object, insert RTF instead of OLE
610 sal_Bool bDoRtf
= false;
611 TransferableObjectDescriptor aObjDesc
;
612 if( aDataHelper
.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
, aObjDesc
) )
614 bDoRtf
= ( ( aObjDesc
.maClassName
== SvGlobalName( SO3_SW_CLASSID
) ||
615 aObjDesc
.maClassName
== SvGlobalName( SO3_SWWEB_CLASSID
) )
616 && aDataHelper
.HasFormat( SOT_FORMAT_RTF
) );
619 nFormatId
= FORMAT_RTF
;
621 nFormatId
= SOT_FORMATSTR_ID_EMBED_SOURCE
;
623 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE
))
624 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE
;
625 // the following format can not affect scenario from #89579#
626 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
))
627 nFormatId
= SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
;
628 // FORMAT_PRIVATE no longer here (can't work if pOwnClip is NULL)
629 else if (aDataHelper
.HasFormat(nBiff8
)) // before xxx_OLE formats
631 else if (aDataHelper
.HasFormat(nBiff5
))
633 else if (aDataHelper
.HasFormat(FORMAT_RTF
))
634 nFormatId
= FORMAT_RTF
;
635 else if (aDataHelper
.HasFormat(SOT_FORMATSTR_ID_HTML
))
636 nFormatId
= SOT_FORMATSTR_ID_HTML
;
637 else if (aDataHelper
.HasFormat(SOT_FORMATSTR_ID_HTML_SIMPLE
))
638 nFormatId
= SOT_FORMATSTR_ID_HTML_SIMPLE
;
639 else if (aDataHelper
.HasFormat(SOT_FORMATSTR_ID_SYLK
))
640 nFormatId
= SOT_FORMATSTR_ID_SYLK
;
641 else if (aDataHelper
.HasFormat(FORMAT_STRING
))
642 nFormatId
= FORMAT_STRING
;
643 else if (aDataHelper
.HasFormat(FORMAT_GDIMETAFILE
))
644 nFormatId
= FORMAT_GDIMETAFILE
;
645 else if (aDataHelper
.HasFormat(FORMAT_BITMAP
))
646 nFormatId
= FORMAT_BITMAP
;
647 // xxx_OLE formats come last, like in SotExchange tables
648 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
))
649 nFormatId
= SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
;
650 else if (aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
))
651 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE_OLE
;
655 PasteDataFormat( nFormatId
, aDataHelper
.GetTransferable(),
656 GetViewData()->GetCurX(), GetViewData()->GetCurY(),
657 NULL
, false, false );
662 sal_Bool
ScViewFunc::PasteFromSystem( sal_uLong nFormatId
, sal_Bool bApi
)
666 sal_Bool bRet
= sal_True
;
667 Window
* pWin
= GetActiveWin();
668 ScTransferObj
* pOwnClip
= ScTransferObj::GetOwnClipboard( pWin
);
669 if ( nFormatId
== 0 && pOwnClip
)
671 // keep a reference in case the clipboard is changed during PasteFromClip
672 uno::Reference
<datatransfer::XTransferable
> aOwnClipRef( pOwnClip
);
673 PasteFromClip( IDF_ALL
, pOwnClip
->GetDocument(),
674 PASTE_NOFUNC
, false, false, false, INS_NONE
, IDF_NONE
,
675 !bApi
); // allow warning dialog
679 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin
) );
680 if ( !aDataHelper
.GetTransferable().is() )
683 bRet
= PasteDataFormat( nFormatId
, aDataHelper
.GetTransferable(),
684 GetViewData()->GetCurX(), GetViewData()->GetCurY(),
685 NULL
, false, !bApi
); // allow warning dialog
687 if ( !bRet
&& !bApi
)
688 ErrorMessage(STR_PASTE_ERROR
);
694 //----------------------------------------------------------------------------
697 sal_Bool
ScViewFunc::PasteOnDrawObject( const uno::Reference
<datatransfer::XTransferable
>& rxTransferable
,
698 SdrObject
* pHitObj
, sal_Bool bLink
)
700 sal_Bool bRet
= false;
703 TransferableDataHelper
aDataHelper( rxTransferable
);
704 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SVXB
) )
706 SotStorageStreamRef xStm
;
707 if( aDataHelper
.GetSotStorageStream( SOT_FORMATSTR_ID_SVXB
, xStm
) )
711 bRet
= ApplyGraphicToObject( pHitObj
, aGraphic
);
714 else if ( aDataHelper
.HasFormat( SOT_FORMAT_GDIMETAFILE
) )
717 if( aDataHelper
.GetGDIMetaFile( FORMAT_GDIMETAFILE
, aMtf
) )
718 bRet
= ApplyGraphicToObject( pHitObj
, Graphic(aMtf
) );
720 else if ( aDataHelper
.HasFormat( SOT_FORMAT_BITMAP
) )
723 if( aDataHelper
.GetBitmap( FORMAT_BITMAP
, aBmp
) )
724 bRet
= ApplyGraphicToObject( pHitObj
, Graphic(aBmp
) );
734 static sal_Bool
lcl_SelHasAttrib( ScDocument
* pDoc
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
735 const ScMarkData
& rTabSelection
, sal_uInt16 nMask
)
737 ScMarkData::const_iterator itr
= rTabSelection
.begin(), itrEnd
= rTabSelection
.end();
738 for (; itr
!= itrEnd
; ++itr
)
739 if ( pDoc
->HasAttrib( nCol1
, nRow1
, *itr
, nCol2
, nRow2
, *itr
, nMask
) )
745 // Einfuegen auf Tabelle:
752 bool checkDestRangeForOverwrite(const ScRangeList
& rDestRanges
, const ScDocument
* pDoc
, const ScMarkData
& rMark
, Window
* pParentWnd
)
754 bool bIsEmpty
= true;
755 ScMarkData::const_iterator itrTab
= rMark
.begin(), itrTabEnd
= rMark
.end();
756 size_t nRangeSize
= rDestRanges
.size();
757 for (; itrTab
!= itrTabEnd
&& bIsEmpty
; ++itrTab
)
759 for (size_t i
= 0; i
< nRangeSize
&& bIsEmpty
; ++i
)
761 const ScRange
& rRange
= *rDestRanges
[i
];
762 bIsEmpty
= pDoc
->IsBlockEmpty(
763 *itrTab
, rRange
.aStart
.Col(), rRange
.aStart
.Row(),
764 rRange
.aEnd
.Col(), rRange
.aEnd
.Row());
770 ScReplaceWarnBox
aBox(pParentWnd
);
771 if (aBox
.Execute() != RET_YES
)
773 // changing the configuration is within the ScReplaceWarnBox
782 bool ScViewFunc::PasteFromClip( sal_uInt16 nFlags
, ScDocument
* pClipDoc
,
783 sal_uInt16 nFunction
, bool bSkipEmpty
,
784 bool bTranspose
, bool bAsLink
,
785 InsCellCmd eMoveMode
, sal_uInt16 nUndoExtraFlags
,
790 OSL_FAIL("PasteFromClip: pClipDoc=0 not allowed");
794 // fuer Undo etc. immer alle oder keine Inhalte sichern
795 sal_uInt16 nContFlags
= IDF_NONE
;
796 if (nFlags
& IDF_CONTENTS
)
797 nContFlags
|= IDF_CONTENTS
;
798 if (nFlags
& IDF_ATTRIB
)
799 nContFlags
|= IDF_ATTRIB
;
800 // evtl. Attribute ins Undo ohne sie vom Clip ins Doc zu kopieren
801 sal_uInt16 nUndoFlags
= nContFlags
;
802 if (nUndoExtraFlags
& IDF_ATTRIB
)
803 nUndoFlags
|= IDF_ATTRIB
;
804 // do not copy note captions into undo document
805 nUndoFlags
|= IDF_NOCAPTIONS
;
807 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
808 if (rClipParam
.isMultiRange())
810 // Source data is multi-range.
811 return PasteMultiRangesFromClip(
812 nFlags
, pClipDoc
, nFunction
, bSkipEmpty
, bTranspose
, bAsLink
, bAllowDialogs
,
813 eMoveMode
, nUndoFlags
);
816 ScMarkData
& rMark
= GetViewData()->GetMarkData();
817 if (rMark
.IsMultiMarked())
819 // Source data is single-range but destination is multi-range.
820 return PasteFromClipToMultiRanges(
821 nFlags
, pClipDoc
, nFunction
, bSkipEmpty
, bTranspose
, bAsLink
, bAllowDialogs
,
822 eMoveMode
, nUndoFlags
);
825 bool bCutMode
= pClipDoc
->IsCutMode(); // if transposing, take from original clipdoc
826 bool bIncludeFiltered
= bCutMode
;
828 // paste drawing: also if IDF_NOTE is set (to create drawing layer for note captions)
829 bool bPasteDraw
= ( pClipDoc
->GetDrawLayer() && ( nFlags
& (IDF_OBJECTS
|IDF_NOTE
) ) );
831 ScDocShellRef aTransShellRef
; // for objects in xTransClip - must remain valid as long as xTransClip
832 ScDocument
* pOrigClipDoc
= NULL
;
833 SAL_WNODEPRECATED_DECLARATIONS_PUSH
834 ::std::auto_ptr
< ScDocument
> xTransClip
;
835 SAL_WNODEPRECATED_DECLARATIONS_POP
840 // include filtered rows until TransposeClip can skip them
841 bIncludeFiltered
= true;
842 pClipDoc
->GetClipArea( nX
, nY
, true );
843 if ( nY
> static_cast<sal_Int32
>(MAXCOL
) ) // zuviele Zeilen zum Transponieren
845 ErrorMessage(STR_PASTE_FULL
);
848 pOrigClipDoc
= pClipDoc
; // fuer Referenzen
852 aTransShellRef
= new ScDocShell
; // DocShell needs a Ref immediately
853 aTransShellRef
->DoInitNew(NULL
);
855 ScDrawLayer::SetGlobalDrawPersist(aTransShellRef
);
857 xTransClip
.reset( new ScDocument( SCDOCMODE_CLIP
));
858 pClipDoc
->TransposeClip( xTransClip
.get(), nFlags
, bAsLink
);
859 pClipDoc
= xTransClip
.get();
861 ScDrawLayer::SetGlobalDrawPersist(NULL
);
872 pClipDoc
->GetClipArea( nClipSizeX
, nClipSizeY
, true ); // size in clipboard doc
874 // size in target doc: include filtered rows only if CutMode is set
877 pClipDoc
->GetClipArea( nDestSizeX
, nDestSizeY
, bIncludeFiltered
);
879 ScDocument
* pDoc
= GetViewData()->GetDocument();
880 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
881 ::svl::IUndoManager
* pUndoMgr
= pDocSh
->GetUndoManager();
882 const bool bRecord(pDoc
->IsUndoEnabled());
884 ScDocShellModificator
aModificator( *pDocSh
);
887 ScMarkData
aFilteredMark( rMark
); // local copy for all modifications
888 ScMarkType eMarkType
= GetViewData()->GetSimpleArea( aMarkRange
, aFilteredMark
);
889 bool bMarkIsFiltered
= (eMarkType
== SC_MARK_SIMPLE_FILTERED
);
890 bool bNoPaste
= ((eMarkType
!= SC_MARK_SIMPLE
&& !bMarkIsFiltered
) ||
891 (bMarkIsFiltered
&& (eMoveMode
!= INS_NONE
|| bAsLink
)));
895 if (!rMark
.IsMarked())
897 // Create a selection with clipboard row count and check that for
899 nStartCol
= GetViewData()->GetCurX();
900 nStartRow
= GetViewData()->GetCurY();
901 nStartTab
= GetViewData()->GetTabNo();
902 nEndCol
= nStartCol
+ nDestSizeX
;
903 nEndRow
= nStartRow
+ nDestSizeY
;
905 aMarkRange
= ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
906 if (ScViewUtil::HasFiltered( aMarkRange
, pDoc
))
908 bMarkIsFiltered
= true;
909 // Fit to clipboard's row count unfiltered rows. If there is no
910 // fit assume that pasting is not possible. Note that nDestSizeY is
911 // size-1 (difference).
912 if (!ScViewUtil::FitToUnfilteredRows( aMarkRange
, pDoc
, nDestSizeY
+1))
915 aFilteredMark
.SetMarkArea( aMarkRange
);
919 // Expand the marked area when the destination area is larger than the
920 // current selection, to get the undo do the right thing. (i#106711)
922 aFilteredMark
.GetMarkArea( aRange
);
923 if( (aRange
.aEnd
.Col() - aRange
.aStart
.Col()) < nDestSizeX
)
925 aRange
.aEnd
.SetCol(aRange
.aStart
.Col() + nDestSizeX
);
926 aFilteredMark
.SetMarkArea(aRange
);
933 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
937 SCROW nUnfilteredRows
= aMarkRange
.aEnd
.Row() - aMarkRange
.aStart
.Row() + 1;
938 ScRangeList aRangeList
;
941 ScViewUtil::UnmarkFiltered( aFilteredMark
, pDoc
);
942 aFilteredMark
.FillRangeListWithMarks( &aRangeList
, false);
944 size_t ListSize
= aRangeList
.size();
945 for ( size_t i
= 0; i
< ListSize
; ++i
)
947 ScRange
* p
= aRangeList
[i
];
948 nUnfilteredRows
+= p
->aEnd
.Row() - p
->aStart
.Row() + 1;
951 /* This isn't needed but could be a desired restriction. */
952 // For filtered, destination rows have to be an exact multiple of
953 // source rows. Note that nDestSizeY is size-1 (difference), so
954 // nDestSizeY==0 fits always.
955 if ((nUnfilteredRows
% (nDestSizeY
+1)) != 0)
957 /* FIXME: this should be a more descriptive error message then. */
958 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
964 // Also for a filtered selection the area is used, for undo et al.
965 if ( aFilteredMark
.IsMarked() || bMarkIsFiltered
)
967 aMarkRange
.GetVars( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
968 SCCOL nBlockAddX
= nEndCol
-nStartCol
;
969 SCROW nBlockAddY
= nEndRow
-nStartRow
;
971 // Nachfrage, wenn die Selektion groesser als 1 Zeile/Spalte, aber kleiner
972 // als das Clipboard ist (dann wird ueber die Selektion hinaus eingefuegt)
974 // ClipSize is not size, but difference
975 if ( ( nBlockAddX
!= 0 && nBlockAddX
< nDestSizeX
) ||
976 ( nBlockAddY
!= 0 && nBlockAddY
< nDestSizeY
) ||
977 ( bMarkIsFiltered
&& nUnfilteredRows
< nDestSizeY
+1 ) )
979 ScWaitCursorOff
aWaitOff( GetFrameWin() );
980 String aMessage
= ScGlobal::GetRscString( STR_PASTE_BIGGER
);
981 QueryBox
aBox( GetViewData()->GetDialogParent(),
982 WinBits(WB_YES_NO
| WB_DEF_NO
), aMessage
);
983 if ( aBox
.Execute() != RET_YES
)
989 if (nBlockAddX
<= nDestSizeX
)
990 nEndCol
= nStartCol
+ nDestSizeX
;
992 if (nBlockAddY
<= nDestSizeY
)
994 nEndRow
= nStartRow
+ nDestSizeY
;
995 if (bMarkIsFiltered
|| nEndRow
> aMarkRange
.aEnd
.Row())
997 // Same as above if nothing was marked: re-fit selection to
998 // unfiltered rows. Extending the selection actually may
999 // introduce filtered rows where there weren't any before, so
1000 // we also need to test for that.
1001 aMarkRange
= ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
1002 if (bMarkIsFiltered
|| ScViewUtil::HasFiltered( aMarkRange
, pDoc
))
1004 bMarkIsFiltered
= true;
1005 // Worst case: all rows up to the end of the sheet are filtered.
1006 if (!ScViewUtil::FitToUnfilteredRows( aMarkRange
, pDoc
, nDestSizeY
+1))
1008 ErrorMessage(STR_PASTE_FULL
);
1012 aMarkRange
.GetVars( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
1013 aFilteredMark
.SetMarkArea( aMarkRange
);
1014 if (bMarkIsFiltered
)
1016 ScViewUtil::UnmarkFiltered( aFilteredMark
, pDoc
);
1017 aFilteredMark
.FillRangeListWithMarks( &aRangeList
, true);
1024 nStartCol
= GetViewData()->GetCurX();
1025 nStartRow
= GetViewData()->GetCurY();
1026 nStartTab
= GetViewData()->GetTabNo();
1027 nEndCol
= nStartCol
+ nDestSizeX
;
1028 nEndRow
= nStartRow
+ nDestSizeY
;
1029 nEndTab
= nStartTab
;
1032 bool bOffLimits
= !ValidCol(nEndCol
) || !ValidRow(nEndRow
);
1034 // Zielbereich, wie er angezeigt wird:
1035 ScRange
aUserRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
1037 // Sollen Zellen eingefuegt werden?
1038 // (zu grosse nEndCol/nEndRow werden weiter unten erkannt)
1039 bool bInsertCells
= ( eMoveMode
!= INS_NONE
&& !bOffLimits
);
1042 // Instead of EnterListAction, the paste undo action is merged into the
1043 // insert action, so Repeat can insert the right cells
1045 MarkRange( aUserRange
); // wird vor CopyFromClip sowieso gesetzt
1047 // CutMode is reset on insertion of cols/rows but needed again on cell move
1048 bool bCut
= pClipDoc
->IsCutMode();
1049 if (!InsertCells( eMoveMode
, bRecord
, true )) // is inserting possible?
1052 // #i21036# EnterListAction isn't used, and InsertCells doesn't insert
1053 // its undo action on failure, so no undo handling is needed here
1056 pClipDoc
->SetCutMode( bCut
);
1058 else if (!bOffLimits
)
1060 bool bAskIfNotEmpty
= bAllowDialogs
&&
1061 ( nFlags
& IDF_CONTENTS
) &&
1062 nFunction
== PASTE_NOFUNC
&&
1063 SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1064 if ( bAskIfNotEmpty
)
1066 ScRangeList aTestRanges
;
1067 aTestRanges
.Append(aUserRange
);
1068 if (!checkDestRangeForOverwrite(aTestRanges
, pDoc
, aFilteredMark
, GetViewData()->GetDialogParent()))
1073 SCCOL nClipStartX
; // Clipboard-Bereich erweitern
1075 pClipDoc
->GetClipStart( nClipStartX
, nClipStartY
);
1076 SCCOL nUndoEndCol
= nClipStartX
+ nClipSizeX
;
1077 SCROW nUndoEndRow
= nClipStartY
+ nClipSizeY
; // end of source area in clipboard document
1078 bool bClipOver
= false;
1079 // #i68690# ExtendMerge for the clip doc must be called with the clipboard's sheet numbers.
1080 // The same end column/row can be used for all calls because the clip doc doesn't contain
1081 // content outside the clip area.
1082 for (SCTAB nClipTab
=0; nClipTab
< pClipDoc
->GetTableCount(); nClipTab
++)
1083 if ( pClipDoc
->HasTable(nClipTab
) )
1084 if ( pClipDoc
->ExtendMerge( nClipStartX
,nClipStartY
, nUndoEndCol
,nUndoEndRow
, nClipTab
, false ) )
1086 nUndoEndCol
-= nClipStartX
+ nClipSizeX
;
1087 nUndoEndRow
-= nClipStartY
+ nClipSizeY
; // now contains only the difference added by ExtendMerge
1088 nUndoEndCol
= sal::static_int_cast
<SCCOL
>( nUndoEndCol
+ nEndCol
);
1089 nUndoEndRow
= sal::static_int_cast
<SCROW
>( nUndoEndRow
+ nEndRow
); // destination area, expanded for merged cells
1091 if (nUndoEndCol
>MAXCOL
|| nUndoEndRow
>MAXROW
)
1093 ErrorMessage(STR_PASTE_FULL
);
1097 pDoc
->ExtendMergeSel( nStartCol
,nStartRow
, nUndoEndCol
,nUndoEndRow
, aFilteredMark
, false );
1099 // Test auf Zellschutz
1101 ScEditableTester
aTester( pDoc
, nStartTab
, nStartCol
,nStartRow
, nUndoEndCol
,nUndoEndRow
);
1102 if (!aTester
.IsEditable())
1104 ErrorMessage(aTester
.GetMessageId());
1108 //! Test auf Ueberlappung
1109 //! nur wirkliche Schnittmenge testen !!!!!!!
1111 ScDocFunc
& rDocFunc
= pDocSh
->GetDocFunc();
1114 String aUndo
= ScGlobal::GetRscString( pClipDoc
->IsCutMode() ? STR_UNDO_MOVE
: STR_UNDO_COPY
);
1115 pUndoMgr
->EnterListAction( aUndo
, aUndo
);
1119 if (lcl_SelHasAttrib( pDoc
, nStartCol
,nStartRow
, nUndoEndCol
,nUndoEndRow
, aFilteredMark
, HASATTR_OVERLAPPED
))
1120 { // "Cell merge not possible if cells already merged"
1121 ScDocAttrIterator
aIter( pDoc
, nStartTab
, nStartCol
, nStartRow
, nUndoEndCol
, nUndoEndRow
);
1122 const ScPatternAttr
* pPattern
= NULL
;
1123 const ScMergeAttr
* pMergeFlag
= NULL
;
1124 const ScMergeFlagAttr
* pMergeFlagAttr
= NULL
;
1128 while ( ( pPattern
= aIter
.GetNext( nCol
, nRow1
, nRow2
) ) != NULL
)
1130 pMergeFlag
= (const ScMergeAttr
*) &pPattern
->GetItem(ATTR_MERGE
);
1131 pMergeFlagAttr
= (const ScMergeFlagAttr
*) &pPattern
->GetItem(ATTR_MERGE_FLAG
);
1132 if( ( pMergeFlag
&& pMergeFlag
->IsMerged() ) || ( pMergeFlagAttr
&& pMergeFlagAttr
->IsOverlapped() ) )
1134 ScRange
aRange(nCol
, nRow1
, nStartTab
);
1135 pDoc
->ExtendOverlapped(aRange
);
1136 pDoc
->ExtendMerge(aRange
, true);
1137 rDocFunc
.UnmergeCells(aRange
, bRecord
);
1144 ScChangeTrack
* pChangeTrack
= pDoc
->GetChangeTrack();
1146 pChangeTrack
->ResetLastCut(); // kein CutMode mehr
1149 bool bColInfo
= ( nStartRow
==0 && nEndRow
==MAXROW
);
1150 bool bRowInfo
= ( nStartCol
==0 && nEndCol
==MAXCOL
);
1152 ScDocument
* pUndoDoc
= NULL
;
1153 ScDocument
* pRefUndoDoc
= NULL
;
1154 ScRefUndoData
* pUndoData
= NULL
;
1158 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1159 pUndoDoc
->InitUndoSelected( pDoc
, aFilteredMark
, bColInfo
, bRowInfo
);
1161 // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
1162 SCTAB nTabCount
= pDoc
->GetTableCount();
1163 pDoc
->CopyToDocument( nStartCol
, nStartRow
, 0, nUndoEndCol
, nUndoEndRow
, nTabCount
-1,
1164 nUndoFlags
, false, pUndoDoc
);
1168 pRefUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1169 pRefUndoDoc
->InitUndo( pDoc
, 0, nTabCount
-1, false, false );
1171 pUndoData
= new ScRefUndoData( pDoc
);
1175 sal_uInt16 nExtFlags
= 0;
1176 pDocSh
->UpdatePaintExt( nExtFlags
, nStartCol
, nStartRow
, nStartTab
,
1177 nEndCol
, nEndRow
, nEndTab
); // content before the change
1179 if (GetViewData()->IsActive())
1184 rMark
.SetMarkArea( aUserRange
);
1188 // Aus Clipboard kopieren,
1189 // wenn gerechnet werden soll, Originaldaten merken
1192 ScDocument
* pMixDoc
= NULL
;
1193 if ( bSkipEmpty
|| nFunction
)
1195 if ( nFlags
& IDF_CONTENTS
)
1197 pMixDoc
= new ScDocument( SCDOCMODE_UNDO
);
1198 pMixDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
);
1199 pDoc
->CopyToDocument( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
,
1200 IDF_CONTENTS
, false, pMixDoc
);
1204 /* Make draw layer and start drawing undo.
1205 - Needed before AdjustBlockHeight to track moved drawing objects.
1206 - Needed before pDoc->CopyFromClip to track inserted note caption objects.
1209 pDocSh
->MakeDrawLayer();
1211 pDoc
->BeginDrawUndo();
1213 sal_uInt16 nNoObjFlags
= nFlags
& ~IDF_OBJECTS
;
1216 // copy normally (original range)
1217 pDoc
->CopyFromClip( aUserRange
, aFilteredMark
, nNoObjFlags
,
1218 pRefUndoDoc
, pClipDoc
, true, false, bIncludeFiltered
,
1219 bSkipEmpty
, (bMarkIsFiltered
? &aRangeList
: NULL
) );
1221 // bei Transpose Referenzen per Hand anpassen
1222 if ( bTranspose
&& bCutMode
&& (nFlags
& IDF_CONTENTS
) )
1223 pDoc
->UpdateTranspose( aUserRange
.aStart
, pOrigClipDoc
, aFilteredMark
, pRefUndoDoc
);
1225 else if (!bTranspose
)
1227 // copy with bAsLink=TRUE
1228 pDoc
->CopyFromClip( aUserRange
, aFilteredMark
, nNoObjFlags
, pRefUndoDoc
, pClipDoc
,
1229 true, true, bIncludeFiltered
, bSkipEmpty
);
1233 // alle Inhalte kopieren (im TransClipDoc stehen nur Formeln)
1234 pDoc
->CopyFromClip( aUserRange
, aFilteredMark
, nContFlags
, pRefUndoDoc
, pClipDoc
);
1237 // skipped rows and merged cells don't mix
1238 if ( !bIncludeFiltered
&& pClipDoc
->HasClipFilteredRows() )
1239 rDocFunc
.UnmergeCells( aUserRange
, false );
1241 pDoc
->ExtendMergeSel( nStartCol
, nStartRow
, nEndCol
, nEndRow
, aFilteredMark
, true ); // Refresh
1244 if ( pMixDoc
) // Rechenfunktionen mit Original-Daten auszufuehren ?
1246 pDoc
->MixDocument( aUserRange
, nFunction
, bSkipEmpty
, pMixDoc
);
1250 AdjustBlockHeight(); // update row heights before pasting objects
1252 ::std::vector
< OUString
> aExcludedChartNames
;
1253 SdrPage
* pPage
= NULL
;
1255 if ( nFlags
& IDF_OBJECTS
)
1257 ScDrawView
* pScDrawView
= GetScDrawView();
1258 SdrModel
* pModel
= ( pScDrawView
? pScDrawView
->GetModel() : NULL
);
1259 pPage
= ( pModel
? pModel
->GetPage( static_cast< sal_uInt16
>( nStartTab
) ) : NULL
);
1262 ScChartHelper::GetChartNames( aExcludedChartNames
, pPage
);
1265 // Paste the drawing objects after the row heights have been updated.
1267 pDoc
->CopyFromClip( aUserRange
, aFilteredMark
, IDF_OBJECTS
, pRefUndoDoc
, pClipDoc
,
1268 true, false, bIncludeFiltered
);
1272 pDocSh
->UpdatePaintExt( nExtFlags
, nStartCol
, nStartRow
, nStartTab
,
1273 nEndCol
, nEndRow
, nEndTab
); // content after the change
1276 // ggf. Autofilter-Koepfe loeschen
1278 if (pDoc
->RefreshAutoFilter( nClipStartX
,nClipStartY
, nClipStartX
+nClipSizeX
,
1279 nClipStartY
+nClipSizeY
, nStartTab
))
1282 ScRange(nClipStartX
, nClipStartY
, nStartTab
, nClipStartX
+nClipSizeX
, nClipStartY
, nStartTab
),
1286 //! Block-Bereich bei RefUndoDoc weglassen !!!
1290 ScDocument
* pRedoDoc
= NULL
;
1291 // Redo-Daten werden erst beim ersten Undo kopiert
1292 // ohne RefUndoDoc muss das Redo-Doc noch nicht angelegt werden
1296 pRedoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1297 pRedoDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
, bColInfo
, bRowInfo
);
1299 // angepasste Referenzen ins Redo-Doc
1301 SCTAB nTabCount
= pDoc
->GetTableCount();
1302 pRedoDoc
->AddUndoTab( 0, nTabCount
-1 );
1303 pDoc
->CopyUpdated( pRefUndoDoc
, pRedoDoc
);
1305 // alte Referenzen ins Undo-Doc
1307 //! Tabellen selektieren ?
1308 pUndoDoc
->AddUndoTab( 0, nTabCount
-1 );
1309 pRefUndoDoc
->DeleteArea( nStartCol
, nStartRow
, nEndCol
, nEndRow
, aFilteredMark
, IDF_ALL
);
1310 pRefUndoDoc
->CopyToDocument( 0,0,0, MAXCOL
,MAXROW
,nTabCount
-1,
1311 IDF_FORMULA
, false, pUndoDoc
);
1315 // DeleteUnchanged for pUndoData is in ScUndoPaste ctor,
1316 // UndoData for redo is made during first undo
1318 ScUndoPasteOptions aOptions
; // store options for repeat
1319 aOptions
.nFunction
= nFunction
;
1320 aOptions
.bSkipEmpty
= bSkipEmpty
;
1321 aOptions
.bTranspose
= bTranspose
;
1322 aOptions
.bAsLink
= bAsLink
;
1323 aOptions
.eMoveMode
= eMoveMode
;
1325 SfxUndoAction
* pUndo
= new ScUndoPaste(
1326 pDocSh
, ScRange(nStartCol
, nStartRow
, nStartTab
, nUndoEndCol
, nUndoEndRow
, nEndTab
),
1327 aFilteredMark
, pUndoDoc
, pRedoDoc
, nFlags
| nUndoFlags
, pUndoData
,
1328 false, &aOptions
); // false = Redo data not yet copied
1332 // Merge the paste undo action into the insert action.
1333 // Use ScUndoWrapper so the ScUndoPaste pointer can be stored in the insert action.
1335 pUndoMgr
->AddUndoAction( new ScUndoWrapper( pUndo
), true );
1338 pUndoMgr
->AddUndoAction( pUndo
);
1339 pUndoMgr
->LeaveListAction();
1342 sal_uInt16 nPaint
= PAINT_GRID
;
1345 nPaint
|= PAINT_TOP
;
1346 nUndoEndCol
= MAXCOL
; // nur zum Zeichnen !
1350 nPaint
|= PAINT_LEFT
;
1351 nUndoEndRow
= MAXROW
; // nur zum Zeichnen !
1354 ScRange(nStartCol
, nStartRow
, nStartTab
, nUndoEndCol
, nUndoEndRow
, nEndTab
),
1356 // AdjustBlockHeight has already been called above
1358 aModificator
.SetDocumentModified();
1359 PostPasteFromClip(aUserRange
, rMark
);
1361 if ( nFlags
& IDF_OBJECTS
)
1363 ScModelObj
* pModelObj
= ( pDocSh
? ScModelObj::getImplementation( pDocSh
->GetModel() ) : NULL
);
1364 if ( pDoc
&& pPage
&& pModelObj
)
1366 bool bSameDoc
= ( rClipParam
.getSourceDocID() == pDoc
->GetDocumentID() );
1367 const ScRangeListVector
& rProtectedChartRangesVector( rClipParam
.maProtectedChartRangesVector
);
1368 ScChartHelper::CreateProtectedChartListenersAndNotify( pDoc
, pPage
, pModelObj
, nStartTab
,
1369 rProtectedChartRangesVector
, aExcludedChartNames
, bSameDoc
);
1376 bool ScViewFunc::PasteMultiRangesFromClip(
1377 sal_uInt16 nFlags
, ScDocument
* pClipDoc
, sal_uInt16 nFunction
,
1378 bool bSkipEmpty
, bool bTranspose
, bool bAsLink
, bool bAllowDialogs
,
1379 InsCellCmd eMoveMode
, sal_uInt16 nUndoFlags
)
1381 ScViewData
& rViewData
= *GetViewData();
1382 ScDocument
* pDoc
= rViewData
.GetDocument();
1383 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
1384 ScMarkData
aMark(rViewData
.GetMarkData());
1385 const ScAddress
& rCurPos
= rViewData
.GetCurPos();
1386 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
1387 SCCOL nColSize
= rClipParam
.getPasteColSize();
1388 SCROW nRowSize
= rClipParam
.getPasteRowSize();
1392 if (static_cast<SCROW
>(rCurPos
.Col()) + nRowSize
-1 > static_cast<SCROW
>(MAXCOL
))
1394 ErrorMessage(STR_PASTE_FULL
);
1398 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1399 ::std::auto_ptr
<ScDocument
> pTransClip(new ScDocument(SCDOCMODE_CLIP
));
1400 SAL_WNODEPRECATED_DECLARATIONS_POP
1401 pClipDoc
->TransposeClip(pTransClip
.get(), nFlags
, bAsLink
);
1402 pClipDoc
= pTransClip
.release();
1403 SCCOL nTempColSize
= nColSize
;
1404 nColSize
= static_cast<SCCOL
>(nRowSize
);
1405 nRowSize
= static_cast<SCROW
>(nTempColSize
);
1408 if (!ValidCol(rCurPos
.Col()+nColSize
-1) || !ValidRow(rCurPos
.Row()+nRowSize
-1))
1410 ErrorMessage(STR_PASTE_FULL
);
1414 // Determine the first and last selected sheet numbers.
1415 SCTAB nTab1
= aMark
.GetFirstSelected();
1416 SCTAB nTab2
= aMark
.GetLastSelected();
1418 ScDocShellModificator
aModificator(*pDocSh
);
1420 // For multi-selection paste, we don't support cell duplication for larger
1421 // destination range. In case the destination is marked, we reset it to
1423 ScRange
aMarkedRange(rCurPos
.Col(), rCurPos
.Row(), nTab1
,
1424 rCurPos
.Col()+nColSize
-1, rCurPos
.Row()+nRowSize
-1, nTab2
);
1426 // Extend the marked range to account for filtered rows in the destination
1428 if (ScViewUtil::HasFiltered(aMarkedRange
, pDoc
))
1430 if (!ScViewUtil::FitToUnfilteredRows(aMarkedRange
, pDoc
, nRowSize
))
1434 bool bAskIfNotEmpty
=
1435 bAllowDialogs
&& (nFlags
& IDF_CONTENTS
) &&
1436 nFunction
== PASTE_NOFUNC
&& SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1440 ScRangeList aTestRanges
;
1441 aTestRanges
.Append(aMarkedRange
);
1442 if (!checkDestRangeForOverwrite(aTestRanges
, pDoc
, aMark
, rViewData
.GetDialogParent()))
1446 aMark
.SetMarkArea(aMarkedRange
);
1447 MarkRange(aMarkedRange
);
1449 bool bInsertCells
= (eMoveMode
!= INS_NONE
);
1452 if (!InsertCells(eMoveMode
, pDoc
->IsUndoEnabled(), true))
1456 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1457 ::std::auto_ptr
<ScDocument
> pUndoDoc
;
1458 SAL_WNODEPRECATED_DECLARATIONS_POP
1459 if (pDoc
->IsUndoEnabled())
1461 pUndoDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
1462 pUndoDoc
->InitUndoSelected(pDoc
, aMark
, false, false);
1463 pDoc
->CopyToDocument(aMarkedRange
, nUndoFlags
, false, pUndoDoc
.get(), &aMark
, true);
1466 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1467 ::std::auto_ptr
<ScDocument
> pMixDoc
;
1468 SAL_WNODEPRECATED_DECLARATIONS_POP
1469 if ( bSkipEmpty
|| nFunction
)
1471 if ( nFlags
& IDF_CONTENTS
)
1473 pMixDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
1474 pMixDoc
->InitUndoSelected(pDoc
, aMark
, false, false);
1475 pDoc
->CopyToDocument(aMarkedRange
, IDF_CONTENTS
, false, pMixDoc
.get(), &aMark
, true);
1479 /* Make draw layer and start drawing undo.
1480 - Needed before AdjustBlockHeight to track moved drawing objects.
1481 - Needed before pDoc->CopyFromClip to track inserted note caption objects.
1483 if (nFlags
& IDF_OBJECTS
)
1484 pDocSh
->MakeDrawLayer();
1485 if (pDoc
->IsUndoEnabled())
1486 pDoc
->BeginDrawUndo();
1488 sal_uInt16 nNoObjFlags
= nFlags
& ~IDF_OBJECTS
;
1489 pDoc
->CopyMultiRangeFromClip(rCurPos
, aMark
, nNoObjFlags
, pClipDoc
,
1490 true, bAsLink
, false, bSkipEmpty
);
1493 pDoc
->MixDocument(aMarkedRange
, nFunction
, bSkipEmpty
, pMixDoc
.get());
1495 AdjustBlockHeight(); // update row heights before pasting objects
1497 if (nFlags
& IDF_OBJECTS
)
1499 // Paste the drawing objects after the row heights have been updated.
1500 pDoc
->CopyMultiRangeFromClip(rCurPos
, aMark
, IDF_OBJECTS
, pClipDoc
,
1501 true, false, false, true);
1504 ScRange aTmp
= aMarkedRange
;
1505 aTmp
.aStart
.SetTab(nTab1
);
1506 aTmp
.aEnd
.SetTab(nTab1
);
1507 pDocSh
->PostPaint(aTmp
, PAINT_GRID
);
1509 if (pDoc
->IsUndoEnabled())
1511 ::svl::IUndoManager
* pUndoMgr
= pDocSh
->GetUndoManager();
1512 String aUndo
= ScGlobal::GetRscString(
1513 pClipDoc
->IsCutMode() ? STR_UNDO_CUT
: STR_UNDO_COPY
);
1514 pUndoMgr
->EnterListAction(aUndo
, aUndo
);
1516 ScUndoPasteOptions aOptions
; // store options for repeat
1517 aOptions
.nFunction
= nFunction
;
1518 aOptions
.bSkipEmpty
= bSkipEmpty
;
1519 aOptions
.bTranspose
= bTranspose
;
1520 aOptions
.bAsLink
= bAsLink
;
1521 aOptions
.eMoveMode
= eMoveMode
;
1523 ScUndoPaste
* pUndo
= new ScUndoPaste(pDocSh
,
1524 aMarkedRange
, aMark
, pUndoDoc
.release(), NULL
, nFlags
|nUndoFlags
, NULL
, false, &aOptions
);
1527 pUndoMgr
->AddUndoAction(new ScUndoWrapper(pUndo
), true);
1529 pUndoMgr
->AddUndoAction(pUndo
, false);
1531 pUndoMgr
->LeaveListAction();
1533 aModificator
.SetDocumentModified();
1534 PostPasteFromClip(aMarkedRange
, aMark
);
1538 bool ScViewFunc::PasteFromClipToMultiRanges(
1539 sal_uInt16 nFlags
, ScDocument
* pClipDoc
, sal_uInt16 nFunction
,
1540 bool bSkipEmpty
, bool bTranspose
, bool bAsLink
, bool bAllowDialogs
,
1541 InsCellCmd eMoveMode
, sal_uInt16 nUndoFlags
)
1545 // We don't allow transpose for this yet.
1546 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
1550 if (eMoveMode
!= INS_NONE
)
1552 // We don't allow insertion mode either. Too complicated.
1553 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
1557 ScViewData
& rViewData
= *GetViewData();
1558 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
1559 if (rClipParam
.mbCutMode
)
1561 // No cut and paste with this, please.
1562 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
1566 const ScAddress
& rCurPos
= rViewData
.GetCurPos();
1567 ScDocument
* pDoc
= rViewData
.GetDocument();
1569 ScRange aSrcRange
= rClipParam
.getWholeRange();
1570 SCROW nRowSize
= aSrcRange
.aEnd
.Row() - aSrcRange
.aStart
.Row() + 1;
1571 SCCOL nColSize
= aSrcRange
.aEnd
.Col() - aSrcRange
.aStart
.Col() + 1;
1573 if (!ValidCol(rCurPos
.Col()+nColSize
-1) || !ValidRow(rCurPos
.Row()+nRowSize
-1))
1575 ErrorMessage(STR_PASTE_FULL
);
1579 ScMarkData
aMark(rViewData
.GetMarkData());
1581 ScRangeList aRanges
;
1582 aMark
.MarkToSimple();
1583 aMark
.FillRangeListWithMarks(&aRanges
, false);
1584 if (!ScClipUtil::CheckDestRanges(pDoc
, nColSize
, nRowSize
, aMark
, aRanges
))
1586 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
1590 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
1592 ScDocShellModificator
aModificator(*pDocSh
);
1594 bool bAskIfNotEmpty
=
1595 bAllowDialogs
&& (nFlags
& IDF_CONTENTS
) &&
1596 nFunction
== PASTE_NOFUNC
&& SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1600 if (!checkDestRangeForOverwrite(aRanges
, pDoc
, aMark
, rViewData
.GetDialogParent()))
1604 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1605 std::auto_ptr
<ScDocument
> pUndoDoc
;
1606 SAL_WNODEPRECATED_DECLARATIONS_POP
1607 if (pDoc
->IsUndoEnabled())
1609 pUndoDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
1610 pUndoDoc
->InitUndoSelected(pDoc
, aMark
, false, false);
1611 for (size_t i
= 0, n
= aRanges
.size(); i
< n
; ++i
)
1613 pDoc
->CopyToDocument(
1614 *aRanges
[i
], nUndoFlags
, false, pUndoDoc
.get(), &aMark
, true);
1618 boost::scoped_ptr
<ScDocument
> pMixDoc
;
1619 if (bSkipEmpty
|| nFunction
)
1621 if (nFlags
& IDF_CONTENTS
)
1623 pMixDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
1624 pMixDoc
->InitUndoSelected(pDoc
, aMark
, false, false);
1625 for (size_t i
= 0, n
= aRanges
.size(); i
< n
; ++i
)
1627 pDoc
->CopyToDocument(
1628 *aRanges
[i
], IDF_CONTENTS
, false, pMixDoc
.get(), &aMark
, true);
1633 if (nFlags
& IDF_OBJECTS
)
1634 pDocSh
->MakeDrawLayer();
1635 if (pDoc
->IsUndoEnabled())
1636 pDoc
->BeginDrawUndo();
1638 // First, paste everything but the drawing objects.
1639 for (size_t i
= 0, n
= aRanges
.size(); i
< n
; ++i
)
1642 *aRanges
[i
], aMark
, (nFlags
& ~IDF_OBJECTS
), NULL
, pClipDoc
,
1643 false, false, true, bSkipEmpty
, NULL
);
1648 for (size_t i
= 0, n
= aRanges
.size(); i
< n
; ++i
)
1649 pDoc
->MixDocument(*aRanges
[i
], nFunction
, bSkipEmpty
, pMixDoc
.get());
1652 AdjustBlockHeight(); // update row heights before pasting objects
1654 // Then paste the objects.
1655 if (nFlags
& IDF_OBJECTS
)
1657 for (size_t i
= 0, n
= aRanges
.size(); i
< n
; ++i
)
1660 *aRanges
[i
], aMark
, IDF_OBJECTS
, NULL
, pClipDoc
,
1661 false, false, true, bSkipEmpty
, NULL
);
1665 // Refresh the range that includes all pasted ranges. We only need to
1666 // refresh the current sheet.
1667 pDocSh
->PostPaint(aRanges
, PAINT_GRID
);
1669 if (pDoc
->IsUndoEnabled())
1671 svl::IUndoManager
* pUndoMgr
= pDocSh
->GetUndoManager();
1672 String aUndo
= ScGlobal::GetRscString(
1673 pClipDoc
->IsCutMode() ? STR_UNDO_CUT
: STR_UNDO_COPY
);
1674 pUndoMgr
->EnterListAction(aUndo
, aUndo
);
1676 ScUndoPasteOptions aOptions
; // store options for repeat
1677 aOptions
.nFunction
= nFunction
;
1678 aOptions
.bSkipEmpty
= bSkipEmpty
;
1679 aOptions
.bTranspose
= bTranspose
;
1680 aOptions
.bAsLink
= bAsLink
;
1681 aOptions
.eMoveMode
= eMoveMode
;
1683 ScUndoPaste
* pUndo
= new ScUndoPaste(
1684 pDocSh
, aRanges
, aMark
, pUndoDoc
.release(), NULL
, nFlags
|nUndoFlags
, NULL
, false, &aOptions
);
1686 pUndoMgr
->AddUndoAction(pUndo
, false);
1687 pUndoMgr
->LeaveListAction();
1689 aModificator
.SetDocumentModified();
1690 PostPasteFromClip(aRanges
, aMark
);
1695 void ScViewFunc::PostPasteFromClip(const ScRangeList
& rPasteRanges
, const ScMarkData
& rMark
)
1697 ScViewData
* pViewData
= GetViewData();
1698 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
1699 pDocSh
->UpdateOle(pViewData
);
1703 // #i97876# Spreadsheet data changes are not notified
1704 ScModelObj
* pModelObj
= ScModelObj::getImplementation( pDocSh
->GetModel() );
1705 if (!pModelObj
|| !pModelObj
->HasChangesListeners())
1708 ScRangeList aChangeRanges
;
1709 for (size_t i
= 0, n
= rPasteRanges
.size(); i
< n
; ++i
)
1711 const ScRange
& r
= *rPasteRanges
[i
];
1712 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1713 for (; itr
!= itrEnd
; ++itr
)
1715 ScRange
aChangeRange(r
);
1716 aChangeRange
.aStart
.SetTab(*itr
);
1717 aChangeRange
.aEnd
.SetTab(*itr
);
1718 aChangeRanges
.Append(aChangeRange
);
1721 pModelObj
->NotifyChanges( OUString( "cell-change" ), aChangeRanges
);
1725 //----------------------------------------------------------------------------
1726 // D R A G A N D D R O P
1728 // innerhalb des Dokuments
1730 sal_Bool
ScViewFunc::MoveBlockTo( const ScRange
& rSource
, const ScAddress
& rDestPos
,
1731 sal_Bool bCut
, sal_Bool bRecord
, sal_Bool bPaint
, sal_Bool bApi
)
1733 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1734 HideAllCursors(); // wegen zusammengefassten
1736 sal_Bool bSuccess
= sal_True
;
1737 SCTAB nDestTab
= rDestPos
.Tab();
1738 const ScMarkData
& rMark
= GetViewData()->GetMarkData();
1739 if ( rSource
.aStart
.Tab() == nDestTab
&& rSource
.aEnd
.Tab() == nDestTab
&& rMark
.GetSelectCount() > 1 )
1741 // moving within one table and several tables selected -> apply to all selected tables
1745 String aUndo
= ScGlobal::GetRscString( bCut
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
1746 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
1749 // collect ranges of consecutive selected tables
1751 ScRange aLocalSource
= rSource
;
1752 ScAddress aLocalDest
= rDestPos
;
1753 SCTAB nTabCount
= pDocSh
->GetDocument()->GetTableCount();
1754 SCTAB nStartTab
= 0;
1755 while ( nStartTab
< nTabCount
&& bSuccess
)
1757 while ( nStartTab
< nTabCount
&& !rMark
.GetTableSelect(nStartTab
) )
1759 if ( nStartTab
< nTabCount
)
1761 SCTAB nEndTab
= nStartTab
;
1762 while ( nEndTab
+1 < nTabCount
&& rMark
.GetTableSelect(nEndTab
+1) )
1765 aLocalSource
.aStart
.SetTab( nStartTab
);
1766 aLocalSource
.aEnd
.SetTab( nEndTab
);
1767 aLocalDest
.SetTab( nStartTab
);
1769 bSuccess
= pDocSh
->GetDocFunc().MoveBlock(
1770 aLocalSource
, aLocalDest
, bCut
, bRecord
, bPaint
, bApi
);
1772 nStartTab
= nEndTab
+ 1;
1777 pDocSh
->GetUndoManager()->LeaveListAction();
1781 // move the block as specified
1782 bSuccess
= pDocSh
->GetDocFunc().MoveBlock(
1783 rSource
, rDestPos
, bCut
, bRecord
, bPaint
, bApi
);
1789 // Zielbereich markieren
1791 rDestPos
.Col() + rSource
.aEnd
.Col() - rSource
.aStart
.Col(),
1792 rDestPos
.Row() + rSource
.aEnd
.Row() - rSource
.aStart
.Row(),
1795 sal_Bool bIncludeFiltered
= bCut
;
1796 if ( !bIncludeFiltered
)
1798 // find number of non-filtered rows
1799 SCROW nPastedCount
= pDocSh
->GetDocument()->CountNonFilteredRows(
1800 rSource
.aStart
.Row(), rSource
.aEnd
.Row(), rSource
.aStart
.Tab());
1802 if ( nPastedCount
== 0 )
1804 aDestEnd
.SetRow( rDestPos
.Row() + nPastedCount
- 1 );
1807 MarkRange( ScRange( rDestPos
, aDestEnd
), false ); //! sal_False ???
1809 pDocSh
->UpdateOle(GetViewData());
1815 // Link innerhalb des Dokuments
1817 sal_Bool
ScViewFunc::LinkBlock( const ScRange
& rSource
, const ScAddress
& rDestPos
, sal_Bool bApi
)
1819 // Test auf Ueberlappung
1821 if ( rSource
.aStart
.Tab() == rDestPos
.Tab() )
1823 SCCOL nDestEndCol
= rDestPos
.Col() + ( rSource
.aEnd
.Col() - rSource
.aStart
.Col() );
1824 SCROW nDestEndRow
= rDestPos
.Row() + ( rSource
.aEnd
.Row() - rSource
.aStart
.Row() );
1826 if ( rSource
.aStart
.Col() <= nDestEndCol
&& rDestPos
.Col() <= rSource
.aEnd
.Col() &&
1827 rSource
.aStart
.Row() <= nDestEndRow
&& rDestPos
.Row() <= rSource
.aEnd
.Row() )
1830 ErrorMessage( STR_ERR_LINKOVERLAP
);
1835 // Ausfuehren per Paste
1837 ScDocument
* pDoc
= GetViewData()->GetDocument();
1838 ScDocument
* pClipDoc
= new ScDocument( SCDOCMODE_CLIP
);
1839 pDoc
->CopyTabToClip( rSource
.aStart
.Col(), rSource
.aStart
.Row(),
1840 rSource
.aEnd
.Col(), rSource
.aEnd
.Row(),
1841 rSource
.aStart
.Tab(), pClipDoc
);
1843 // Zielbereich markieren (Cursor setzen, keine Markierung)
1845 if ( GetViewData()->GetTabNo() != rDestPos
.Tab() )
1846 SetTabNo( rDestPos
.Tab() );
1848 MoveCursorAbs( rDestPos
.Col(), rDestPos
.Row(), SC_FOLLOW_NONE
, false, false );
1852 PasteFromClip( IDF_ALL
, pClipDoc
, PASTE_NOFUNC
, false, false, sal_True
); // als Link
1859 void ScViewFunc::DataFormPutData( SCROW nCurrentRow
,
1860 SCROW nStartRow
, SCCOL nStartCol
,
1861 SCROW nEndRow
, SCCOL nEndCol
,
1862 boost::ptr_vector
<boost::nullable
<Edit
> >& aEdits
,
1863 sal_uInt16 aColLength
)
1865 ScDocument
* pDoc
= GetViewData()->GetDocument();
1866 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1867 ScMarkData
& rMark
= GetViewData()->GetMarkData();
1868 ScDocShellModificator
aModificator( *pDocSh
);
1869 ::svl::IUndoManager
* pUndoMgr
= pDocSh
->GetUndoManager();
1872 const sal_Bool
bRecord( pDoc
->IsUndoEnabled());
1873 ScDocument
* pUndoDoc
= NULL
;
1874 ScDocument
* pRedoDoc
= NULL
;
1875 ScRefUndoData
* pUndoData
= NULL
;
1876 SCTAB nTab
= GetViewData()->GetTabNo();
1877 SCTAB nStartTab
= nTab
;
1878 SCTAB nEndTab
= nTab
;
1881 ScChangeTrack
* pChangeTrack
= pDoc
->GetChangeTrack();
1883 pChangeTrack
->ResetLastCut(); // kein CutMode mehr
1885 ScRange
aUserRange( nStartCol
, nCurrentRow
, nStartTab
, nEndCol
, nCurrentRow
, nEndTab
);
1886 sal_Bool bColInfo
= ( nStartRow
==0 && nEndRow
==MAXROW
);
1887 sal_Bool bRowInfo
= ( nStartCol
==0 && nEndCol
==MAXCOL
);
1888 SCCOL nUndoEndCol
= nStartCol
+aColLength
-1;
1889 SCROW nUndoEndRow
= nCurrentRow
;
1890 sal_uInt16 nUndoFlags
= IDF_NONE
;
1894 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1895 pUndoDoc
->InitUndoSelected( pDoc
, rMark
, bColInfo
, bRowInfo
);
1896 pDoc
->CopyToDocument( aUserRange
, 1 , false , pUndoDoc
);
1898 sal_uInt16 nExtFlags
= 0;
1899 pDocSh
->UpdatePaintExt( nExtFlags
, nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
); // content before the change
1900 pDoc
->BeginDrawUndo();
1902 for(sal_uInt16 i
= 0; i
< aColLength
; i
++)
1904 if (!aEdits
.is_null(i
))
1906 String aFieldName
=aEdits
[i
].GetText();
1907 pDoc
->SetString( nStartCol
+ i
, nCurrentRow
, nTab
, aFieldName
);
1910 pDocSh
->UpdatePaintExt( nExtFlags
, nStartCol
, nCurrentRow
, nStartTab
, nEndCol
, nCurrentRow
, nEndTab
); // content after the change
1911 SfxUndoAction
* pUndo
= new ScUndoDataForm( pDocSh
,
1912 nStartCol
, nCurrentRow
, nStartTab
,
1913 nUndoEndCol
, nUndoEndRow
, nEndTab
, rMark
,
1914 pUndoDoc
, pRedoDoc
, nUndoFlags
,
1915 pUndoData
, NULL
, NULL
, NULL
,
1916 false ); // FALSE = Redo data not yet copied
1917 pUndoMgr
->AddUndoAction( new ScUndoWrapper( pUndo
), true );
1919 sal_uInt16 nPaint
= PAINT_GRID
;
1922 nPaint
|= PAINT_TOP
;
1923 nUndoEndCol
= MAXCOL
; // nur zum Zeichnen !
1927 nPaint
|= PAINT_LEFT
;
1928 nUndoEndRow
= MAXROW
; // nur zum Zeichnen !
1932 ScRange(nStartCol
, nCurrentRow
, nStartTab
, nUndoEndCol
, nUndoEndRow
, nEndTab
),
1934 pDocSh
->UpdateOle(GetViewData());
1939 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */