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 <editeng/eeitem.hxx>
22 #include <editeng/justifyitem.hxx>
24 #include <com/sun/star/uno/Sequence.hxx>
25 #include <com/sun/star/embed/XTransactedObject.hpp>
27 #include <unotools/tempfile.hxx>
28 #include <unotools/ucbstreamhelper.hxx>
29 #include <comphelper/storagehelper.hxx>
30 #include <comphelper/servicehelper.hxx>
31 #include <sot/storage.hxx>
32 #include <vcl/svapp.hxx>
33 #include <vcl/virdev.hxx>
34 #include <osl/mutex.hxx>
35 #include <sfx2/app.hxx>
36 #include <sfx2/docfile.hxx>
38 #include "transobj.hxx"
39 #include "patattr.hxx"
40 #include "cellvalue.hxx"
41 #include "cellform.hxx"
42 #include "document.hxx"
43 #include "viewopti.hxx"
44 #include "editutil.hxx"
46 #include "formulacell.hxx"
47 #include "printfun.hxx"
48 #include "docfunc.hxx"
50 #include "dragdata.hxx"
51 #include "clipdata.hxx"
52 #include "clipparam.hxx"
54 #include <editeng/paperinf.hxx>
55 #include <editeng/sizeitem.hxx>
56 #include <svx/algitem.hxx>
57 #include <svl/intitem.hxx>
58 #include <svl/zforlist.hxx>
60 #include "markdata.hxx"
61 #include "stlpool.hxx"
62 #include "viewdata.hxx"
63 #include "dociter.hxx"
64 #include "cellsuno.hxx"
65 #include "stringutil.hxx"
66 #include "formulaiter.hxx"
67 #include <gridwin.hxx>
69 using namespace com::sun::star
;
71 #define SCTRANS_TYPE_IMPEX SotClipboardFormatId::STRING
72 #define SCTRANS_TYPE_EDIT_RTF SotClipboardFormatId::BITMAP
73 #define SCTRANS_TYPE_EDIT_BIN SotClipboardFormatId::GDIMETAFILE
74 #define SCTRANS_TYPE_EMBOBJ SotClipboardFormatId::PRIVATE
76 void ScTransferObj::GetAreaSize( ScDocument
* pDoc
, SCTAB nTab1
, SCTAB nTab2
, SCROW
& nRow
, SCCOL
& nCol
)
80 for( SCTAB nTab
= nTab1
; nTab
<= nTab2
; nTab
++ )
84 // GetPrintArea instead of GetCellArea - include drawing objects
85 if( pDoc
->GetPrintArea( nTab
, nLastCol
, nLastRow
) )
87 if( nLastCol
> nMaxCol
)
89 if( nLastRow
> nMaxRow
)
97 void ScTransferObj::PaintToDev( OutputDevice
* pDev
, ScDocument
* pDoc
, double nPrintFactor
,
98 const ScRange
& rBlock
, bool bMetaFile
)
104 Rectangle
aBound( aPoint
, pDev
->GetOutputSize() ); //! use size from clip area?
106 ScViewData
aViewData(nullptr,nullptr);
107 aViewData
.InitData( pDoc
);
109 aViewData
.SetTabNo( rBlock
.aEnd
.Tab() );
110 aViewData
.SetScreen( rBlock
.aStart
.Col(), rBlock
.aStart
.Row(),
111 rBlock
.aEnd
.Col(), rBlock
.aEnd
.Row() );
113 ScPrintFunc::DrawToDev( pDoc
, pDev
, nPrintFactor
, aBound
, &aViewData
, bMetaFile
);
116 ScTransferObj::ScTransferObj( ScDocument
* pClipDoc
, const TransferableObjectDescriptor
& rDesc
) :
122 nSourceCursorX( MAXCOL
+ 1 ),
123 nSourceCursorY( MAXROW
+ 1 ),
124 nDragSourceFlags( 0 ),
125 bDragWasInternal( false ),
126 bUsedForLink( false ),
129 OSL_ENSURE(pDoc
->IsClipboard(), "wrong document");
131 // get aBlock from clipboard doc
137 pDoc
->GetClipStart( nCol1
, nRow1
);
138 pDoc
->GetClipArea( nCol2
, nRow2
, true ); // real source area - include filtered rows
139 nCol2
= sal::static_int_cast
<SCCOL
>( nCol2
+ nCol1
);
140 nRow2
= sal::static_int_cast
<SCROW
>( nRow2
+ nRow1
);
143 pDoc
->GetClipArea( nDummy
, nNonFiltered
, false );
144 bHasFiltered
= (nNonFiltered
< (nRow2
- nRow1
));
145 ++nNonFiltered
; // to get count instead of diff
150 for (SCTAB i
=0; i
< pDoc
->GetTableCount(); i
++)
151 if (pDoc
->HasTable(i
))
158 OSL_ENSURE(!bFirst
, "no sheet selected");
160 // only limit to used cells if whole sheet was marked
161 // (so empty cell areas can be copied)
162 if ( nCol2
>=MAXCOL
&& nRow2
>=MAXROW
)
166 GetAreaSize( pDoc
, nTab1
, nTab2
, nMaxRow
, nMaxCol
);
167 if( nMaxRow
< nRow2
)
169 if( nMaxCol
< nCol2
)
173 aBlock
= ScRange( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
174 nVisibleTab
= nTab1
; // valid table as default
176 Rectangle aMMRect
= pDoc
->GetMMRect( nCol1
,nRow1
, nCol2
,nRow2
, nTab1
);
177 aObjDesc
.maSize
= aMMRect
.GetSize();
178 PrepareOLE( aObjDesc
);
181 ScTransferObj::~ScTransferObj()
183 SolarMutexGuard aSolarGuard
;
185 ScModule
* pScMod
= SC_MOD();
186 if ( pScMod
->GetClipData().pCellClipboard
== this )
188 OSL_FAIL("ScTransferObj wasn't released");
189 pScMod
->SetClipObject( nullptr, nullptr );
191 if ( pScMod
->GetDragData().pCellTransfer
== this )
193 OSL_FAIL("ScTransferObj wasn't released");
194 pScMod
->ResetDragObject();
197 delete pDoc
; // ScTransferObj is owner of clipboard document
199 aDocShellRef
.Clear(); // before releasing the mutex
201 aDrawPersistRef
.Clear(); // after the model
205 ScTransferObj
* ScTransferObj::GetOwnClipboard( vcl::Window
* pUIWin
)
207 ScTransferObj
* pObj
= SC_MOD()->GetClipData().pCellClipboard
;
208 if ( pObj
&& pUIWin
)
210 // check formats to see if pObj is really in the system clipboard
212 // pUIWin is NULL when called from core (IsClipboardSource),
213 // in that case don't access the system clipboard, because the call
214 // may be from other clipboard operations (like flushing, #86059#)
216 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pUIWin
) );
217 if ( !aDataHelper
.HasFormat( SotClipboardFormatId::DIF
) )
219 // OSL_FAIL("ScTransferObj wasn't released");
226 void ScTransferObj::AddSupportedFormats()
228 AddFormat( SotClipboardFormatId::EMBED_SOURCE
);
229 AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR
);
230 AddFormat( SotClipboardFormatId::GDIMETAFILE
);
231 AddFormat( SotClipboardFormatId::PNG
);
232 AddFormat( SotClipboardFormatId::BITMAP
);
234 // ScImportExport formats
235 AddFormat( SotClipboardFormatId::HTML
);
236 AddFormat( SotClipboardFormatId::SYLK
);
237 AddFormat( SotClipboardFormatId::LINK
);
238 AddFormat( SotClipboardFormatId::DIF
);
239 AddFormat( SotClipboardFormatId::STRING
);
241 AddFormat( SotClipboardFormatId::RTF
);
242 if ( aBlock
.aStart
== aBlock
.aEnd
)
243 AddFormat( SotClipboardFormatId::EDITENGINE
);
246 bool ScTransferObj::GetData( const datatransfer::DataFlavor
& rFlavor
, const OUString
& /*rDestDoc*/ )
248 SotClipboardFormatId nFormat
= SotExchange::GetFormat( rFlavor
);
251 if( HasFormat( nFormat
) )
253 if ( nFormat
== SotClipboardFormatId::LINKSRCDESCRIPTOR
|| nFormat
== SotClipboardFormatId::OBJECTDESCRIPTOR
)
255 bOK
= SetTransferableObjectDescriptor( aObjDesc
, rFlavor
);
257 else if ( ( nFormat
== SotClipboardFormatId::RTF
|| nFormat
== SotClipboardFormatId::EDITENGINE
) &&
258 aBlock
.aStart
== aBlock
.aEnd
)
260 // RTF from a single cell is handled by EditEngine
262 SCCOL nCol
= aBlock
.aStart
.Col();
263 SCROW nRow
= aBlock
.aStart
.Row();
264 SCTAB nTab
= aBlock
.aStart
.Tab();
265 ScAddress
aPos(nCol
, nRow
, nTab
);
267 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
268 ScTabEditEngine
aEngine( *pPattern
, pDoc
->GetEditPool() );
269 ScRefCellValue
aCell(*pDoc
, aPos
);
270 if (aCell
.meType
== CELLTYPE_EDIT
)
272 const EditTextObject
* pObj
= aCell
.mpEditText
;
273 aEngine
.SetText(*pObj
);
277 SvNumberFormatter
* pFormatter
= pDoc
->GetFormatTable();
278 sal_uLong nNumFmt
= pPattern
->GetNumberFormat(pFormatter
);
281 ScCellFormat::GetString(aCell
, nNumFmt
, aText
, &pColor
, *pFormatter
, pDoc
);
282 if (!aText
.isEmpty())
283 aEngine
.SetText(aText
);
286 bOK
= SetObject( &aEngine
,
287 (nFormat
== SotClipboardFormatId::RTF
) ? SCTRANS_TYPE_EDIT_RTF
: SCTRANS_TYPE_EDIT_BIN
,
290 else if ( ScImportExport::IsFormatSupported( nFormat
) || nFormat
== SotClipboardFormatId::RTF
)
292 // if this transfer object was used to create a DDE link, filtered rows
293 // have to be included for subsequent calls (to be consistent with link data)
294 if ( nFormat
== SotClipboardFormatId::LINK
)
297 bool bIncludeFiltered
= pDoc
->IsCutMode() || bUsedForLink
;
299 bool bReduceBlockFormat
= nFormat
== SotClipboardFormatId::HTML
|| nFormat
== SotClipboardFormatId::RTF
;
300 ScRange aReducedBlock
= aBlock
;
301 if (bReduceBlockFormat
&& (aBlock
.aEnd
.Col() == MAXCOL
|| aBlock
.aEnd
.Row() == MAXROW
) && aBlock
.aStart
.Tab() == aBlock
.aEnd
.Tab())
303 bool bShrunk
= false;
304 //shrink the area to allow pasting to external applications
305 SCCOL aStartCol
= aReducedBlock
.aStart
.Col();
306 SCROW aStartRow
= aReducedBlock
.aStart
.Row();
307 SCCOL aEndCol
= aReducedBlock
.aEnd
.Col();
308 SCROW aEndRow
= aReducedBlock
.aEnd
.Row();
309 pDoc
->ShrinkToUsedDataArea( bShrunk
, aReducedBlock
.aStart
.Tab(), aStartCol
, aStartRow
, aEndCol
, aEndRow
, false);
310 aReducedBlock
= ScRange(aStartCol
, aStartRow
, aReducedBlock
.aStart
.Tab(), aEndCol
, aEndRow
, aReducedBlock
.aEnd
.Tab());
313 ScImportExport
aObj( pDoc
, aReducedBlock
);
314 ScExportTextOptions
aTextOptions(ScExportTextOptions::None
, 0, true);
317 // For a DDE link, convert line breaks and separators to space.
318 aTextOptions
.meNewlineConversion
= ScExportTextOptions::ToSpace
;
319 aTextOptions
.mcSeparatorConvertTo
= ' ';
320 aTextOptions
.mbAddQuotes
= false;
322 aObj
.SetExportTextOptions(aTextOptions
);
323 aObj
.SetFormulas( pDoc
->GetViewOptions().GetOption( VOPT_FORMULAS
) );
324 aObj
.SetIncludeFiltered( bIncludeFiltered
);
326 // DataType depends on format type:
328 if ( rFlavor
.DataType
.equals( ::cppu::UnoType
<OUString
>::get() ) )
331 if ( aObj
.ExportString( aString
, nFormat
) )
332 bOK
= SetString( aString
, rFlavor
);
334 else if ( rFlavor
.DataType
.equals( cppu::UnoType
<uno::Sequence
< sal_Int8
>>::get() ) )
336 // SetObject converts a stream into a Int8-Sequence
337 bOK
= SetObject( &aObj
, SCTRANS_TYPE_IMPEX
, rFlavor
);
341 OSL_FAIL("unknown DataType");
344 else if ( nFormat
== SotClipboardFormatId::BITMAP
|| nFormat
== SotClipboardFormatId::PNG
)
346 Rectangle aMMRect
= pDoc
->GetMMRect( aBlock
.aStart
.Col(), aBlock
.aStart
.Row(),
347 aBlock
.aEnd
.Col(), aBlock
.aEnd
.Row(),
348 aBlock
.aStart
.Tab() );
349 ScopedVclPtrInstance
< VirtualDevice
> pVirtDev
;
350 pVirtDev
->SetOutputSizePixel( pVirtDev
->LogicToPixel( aMMRect
.GetSize(), MAP_100TH_MM
) );
352 PaintToDev( pVirtDev
, pDoc
, 1.0, aBlock
, false );
354 pVirtDev
->SetMapMode( MapMode( MAP_PIXEL
) );
355 Bitmap aBmp
= pVirtDev
->GetBitmap( Point(), pVirtDev
->GetOutputSize() );
356 bOK
= SetBitmapEx( aBmp
, rFlavor
);
358 else if ( nFormat
== SotClipboardFormatId::GDIMETAFILE
)
360 // #i123405# Do not limit visual size calculation for metafile creation.
361 // It seems unlikely that removing the limitation causes problems since
362 // metafile creation means that no real pixel device in the needed size is
366 SfxObjectShell
* pEmbObj
= aDocShellRef
;
368 // like SvEmbeddedTransfer::GetData:
370 ScopedVclPtrInstance
< VirtualDevice
> pVDev
;
371 MapMode
aMapMode( pEmbObj
->GetMapUnit() );
372 Rectangle
aVisArea( pEmbObj
->GetVisArea( ASPECT_CONTENT
) );
374 pVDev
->EnableOutput( false );
375 pVDev
->SetMapMode( aMapMode
);
376 aMtf
.SetPrefSize( aVisArea
.GetSize() );
377 aMtf
.SetPrefMapMode( aMapMode
);
378 aMtf
.Record( pVDev
);
380 pEmbObj
->DoDraw( pVDev
, Point(), aVisArea
.GetSize(), JobSetup() );
385 bOK
= SetGDIMetaFile( aMtf
, rFlavor
);
387 else if ( nFormat
== SotClipboardFormatId::EMBED_SOURCE
)
389 //TODO/LATER: differentiate between formats?!
390 // #i123405# Do limit visual size calculation to PageSize
391 InitDocShell(true); // set aDocShellRef
393 SfxObjectShell
* pEmbObj
= aDocShellRef
;
394 bOK
= SetObject( pEmbObj
, SCTRANS_TYPE_EMBOBJ
, rFlavor
);
400 bool ScTransferObj::WriteObject( tools::SvRef
<SotStorageStream
>& rxOStm
, void* pUserObject
, SotClipboardFormatId nUserObjectId
,
401 const datatransfer::DataFlavor
& rFlavor
)
403 // called from SetObject, put data into stream
406 switch (nUserObjectId
)
408 case SCTRANS_TYPE_IMPEX
:
410 ScImportExport
* pImpEx
= static_cast<ScImportExport
*>(pUserObject
);
412 SotClipboardFormatId nFormat
= SotExchange::GetFormat( rFlavor
);
413 // mba: no BaseURL for data exchange
414 if ( pImpEx
->ExportStream( *rxOStm
, OUString(), nFormat
) )
415 bRet
= ( rxOStm
->GetError() == ERRCODE_NONE
);
419 case SCTRANS_TYPE_EDIT_RTF
:
420 case SCTRANS_TYPE_EDIT_BIN
:
422 ScTabEditEngine
* pEngine
= static_cast<ScTabEditEngine
*>(pUserObject
);
423 if ( nUserObjectId
== SCTRANS_TYPE_EDIT_RTF
)
425 pEngine
->Write( *rxOStm
, EE_FORMAT_RTF
);
426 bRet
= ( rxOStm
->GetError() == ERRCODE_NONE
);
430 // can't use Write for EditEngine format because that would
431 // write old format without support for unicode characters.
432 // Get the data from the EditEngine's transferable instead.
434 sal_Int32 nParCnt
= pEngine
->GetParagraphCount();
437 ESelection
aSel( 0, 0, nParCnt
-1, pEngine
->GetTextLen(nParCnt
-1) );
439 uno::Reference
<datatransfer::XTransferable
> xEditTrans
= pEngine
->CreateTransferable( aSel
);
440 TransferableDataHelper
aEditHelper( xEditTrans
);
442 bRet
= aEditHelper
.GetSotStorageStream( rFlavor
, rxOStm
);
447 case SCTRANS_TYPE_EMBOBJ
:
450 SfxObjectShell
* pEmbObj
= static_cast<SfxObjectShell
*>(pUserObject
);
451 ::utl::TempFile aTempFile
;
452 aTempFile
.EnableKillingFile();
453 uno::Reference
< embed::XStorage
> xWorkStore
=
454 ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile
.GetURL(), embed::ElementModes::READWRITE
);
456 // write document storage
457 pEmbObj
->SetupStorage( xWorkStore
, SOFFICE_FILEFORMAT_CURRENT
, false );
459 // mba: no relative URLs for clipboard!
460 SfxMedium
aMedium( xWorkStore
, OUString() );
461 pEmbObj
->DoSaveObjectAs( aMedium
, false );
462 pEmbObj
->DoSaveCompleted();
464 uno::Reference
< embed::XTransactedObject
> xTransact( xWorkStore
, uno::UNO_QUERY
);
465 if ( xTransact
.is() )
468 SvStream
* pSrcStm
= ::utl::UcbStreamHelper::CreateStream( aTempFile
.GetURL(), StreamMode::READ
);
471 rxOStm
->SetBufferSize( 0xff00 );
472 rxOStm
->WriteStream( *pSrcStm
);
478 xWorkStore
->dispose();
485 OSL_FAIL("unknown object id");
490 void ScTransferObj::ObjectReleased()
492 ScModule
* pScMod
= SC_MOD();
493 if ( pScMod
->GetClipData().pCellClipboard
== this )
494 pScMod
->SetClipObject( nullptr, nullptr );
496 TransferableHelper::ObjectReleased();
499 void ScTransferObj::DragFinished( sal_Int8 nDropAction
)
501 if ( nDropAction
== DND_ACTION_MOVE
&& !bDragWasInternal
&& !(nDragSourceFlags
& SC_DROP_NAVIGATOR
) )
503 // move: delete source data
504 ScDocShell
* pSourceSh
= GetSourceDocShell();
507 ScMarkData aMarkData
= GetSourceMarkData();
508 // external drag&drop doesn't copy objects, so they also aren't deleted:
509 // bApi=TRUE, don't show error messages from drag&drop
510 pSourceSh
->GetDocFunc().DeleteContents( aMarkData
, InsertDeleteFlags::ALL
& ~InsertDeleteFlags::OBJECTS
, true, true );
514 ScModule
* pScMod
= SC_MOD();
515 if ( pScMod
->GetDragData().pCellTransfer
== this )
516 pScMod
->ResetDragObject();
518 xDragSourceRanges
= nullptr; // don't keep source after dropping
520 TransferableHelper::DragFinished( nDropAction
);
523 void ScTransferObj::SetDragHandlePos( SCCOL nX
, SCROW nY
)
529 void ScTransferObj::SetSourceCursorPos( SCCOL nX
, SCROW nY
)
535 bool ScTransferObj::WasSourceCursorInSelection() const
538 nSourceCursorX
>= aBlock
.aStart
.Col() && nSourceCursorX
<= aBlock
.aEnd
.Col() &&
539 nSourceCursorY
>= aBlock
.aStart
.Row() && nSourceCursorY
<= aBlock
.aEnd
.Row();
542 void ScTransferObj::SetVisibleTab( SCTAB nNew
)
547 void ScTransferObj::SetDrawPersist( const SfxObjectShellRef
& rRef
)
549 aDrawPersistRef
= rRef
;
552 void ScTransferObj::SetDragSource( ScDocShell
* pSourceShell
, const ScMarkData
& rMark
)
555 rMark
.FillRangeListWithMarks( &aRanges
, false );
556 xDragSourceRanges
= new ScCellRangesObj( pSourceShell
, aRanges
);
559 void ScTransferObj::SetDragSourceFlags( sal_uInt16 nFlags
)
561 nDragSourceFlags
= nFlags
;
564 void ScTransferObj::SetDragWasInternal()
566 bDragWasInternal
= true;
569 void ScTransferObj::SetUseInApi( bool bSet
)
574 ScDocument
* ScTransferObj::GetSourceDocument()
576 ScDocShell
* pSourceDocSh
= GetSourceDocShell();
578 return &pSourceDocSh
->GetDocument();
582 ScDocShell
* ScTransferObj::GetSourceDocShell()
584 ScCellRangesBase
* pRangesObj
= ScCellRangesBase::getImplementation( xDragSourceRanges
);
586 return pRangesObj
->GetDocShell();
588 return nullptr; // none set
591 ScMarkData
ScTransferObj::GetSourceMarkData()
593 ScMarkData aMarkData
;
594 ScCellRangesBase
* pRangesObj
= ScCellRangesBase::getImplementation( xDragSourceRanges
);
597 const ScRangeList
& rRanges
= pRangesObj
->GetRangeList();
598 aMarkData
.MarkFromRangeList( rRanges
, false );
603 // initialize aDocShellRef with a live document from the ClipDoc
605 // #i123405# added parameter to allow size calculation without limitation
606 // to PageSize, e.g. used for Metafile creation for clipboard.
608 void ScTransferObj::InitDocShell(bool bLimitToPageSize
)
610 if ( !aDocShellRef
.Is() )
612 ScDocShell
* pDocSh
= new ScDocShell
;
613 aDocShellRef
= pDocSh
; // ref must be there before InitNew
617 ScDocument
& rDestDoc
= pDocSh
->GetDocument();
618 ScMarkData aDestMark
;
619 aDestMark
.SelectTable( 0, true );
621 rDestDoc
.SetDocOptions( pDoc
->GetDocOptions() ); // #i42666#
624 pDoc
->GetName( aBlock
.aStart
.Tab(), aTabName
);
625 rDestDoc
.RenameTab( 0, aTabName
, false ); // no UpdateRef (empty)
627 rDestDoc
.CopyStdStylesFrom( pDoc
);
629 SCCOL nStartX
= aBlock
.aStart
.Col();
630 SCROW nStartY
= aBlock
.aStart
.Row();
631 SCCOL nEndX
= aBlock
.aEnd
.Col();
632 SCROW nEndY
= aBlock
.aEnd
.Row();
635 // (must be copied before CopyFromClip, for drawing objects)
638 SCTAB nSrcTab
= aBlock
.aStart
.Tab();
639 rDestDoc
.SetLayoutRTL(0, pDoc
->IsLayoutRTL(nSrcTab
));
640 for (nCol
=nStartX
; nCol
<=nEndX
; nCol
++)
641 if ( pDoc
->ColHidden(nCol
, nSrcTab
) )
642 rDestDoc
.ShowCol( nCol
, 0, false );
644 rDestDoc
.SetColWidth( nCol
, 0, pDoc
->GetColWidth( nCol
, nSrcTab
) );
646 for (SCROW nRow
= nStartY
; nRow
<= nEndY
; ++nRow
)
648 if ( pDoc
->RowHidden(nRow
, nSrcTab
) )
649 rDestDoc
.ShowRow( nRow
, 0, false );
652 rDestDoc
.SetRowHeight( nRow
, 0, pDoc
->GetOriginalHeight( nRow
, nSrcTab
) );
654 // if height was set manually, that flag has to be copied, too
655 bool bManual
= pDoc
->IsManualRowHeight(nRow
, nSrcTab
);
656 rDestDoc
.SetManualHeight(nRow
, nRow
, 0, bManual
);
660 if (pDoc
->GetDrawLayer() || pDoc
->HasNotes())
661 pDocSh
->MakeDrawLayer();
663 // cell range is copied to the original position, but on the first sheet
664 // -> bCutMode must be set
665 // pDoc is always a Clipboard-document
667 ScRange
aDestRange( nStartX
,nStartY
,0, nEndX
,nEndY
,0 );
668 bool bWasCut
= pDoc
->IsCutMode();
670 pDoc
->SetClipArea( aDestRange
, true ); // Cut
671 rDestDoc
.CopyFromClip( aDestRange
, aDestMark
, InsertDeleteFlags::ALL
, nullptr, pDoc
, false );
672 pDoc
->SetClipArea( aDestRange
, bWasCut
);
674 StripRefs( pDoc
, nStartX
,nStartY
, nEndX
,nEndY
, &rDestDoc
);
676 ScRange aMergeRange
= aDestRange
;
677 rDestDoc
.ExtendMerge( aMergeRange
, true );
679 pDoc
->CopyDdeLinks( &rDestDoc
); // copy values of DDE Links
681 // page format (grid etc) and page size (maximum size for ole object)
683 Size aPaperSize
= SvxPaperInfo::GetPaperSize( PAPER_A4
); // Twips
684 ScStyleSheetPool
* pStylePool
= pDoc
->GetStyleSheetPool();
685 OUString aStyleName
= pDoc
->GetPageStyle( aBlock
.aStart
.Tab() );
686 SfxStyleSheetBase
* pStyleSheet
= pStylePool
->Find( aStyleName
, SfxStyleFamily::Page
);
689 const SfxItemSet
& rSourceSet
= pStyleSheet
->GetItemSet();
690 aPaperSize
= static_cast<const SvxSizeItem
&>( rSourceSet
.Get(ATTR_PAGE_SIZE
)).GetSize();
692 // CopyStyleFrom kopiert SetItems mit richtigem Pool
693 ScStyleSheetPool
* pDestPool
= rDestDoc
.GetStyleSheetPool();
694 pDestPool
->CopyStyleFrom( pStylePool
, aStyleName
, SfxStyleFamily::Page
);
697 ScViewData
aViewData( pDocSh
, nullptr );
698 aViewData
.SetScreen( nStartX
,nStartY
, nEndX
,nEndY
);
699 aViewData
.SetCurX( nStartX
);
700 aViewData
.SetCurY( nStartY
);
702 rDestDoc
.SetViewOptions( pDoc
->GetViewOptions() );
705 //! get while copying sizes
710 for (nCol
=0; nCol
<nStartX
; nCol
++)
711 nPosX
+= rDestDoc
.GetColWidth( nCol
, 0 );
712 nPosY
+= rDestDoc
.GetRowHeight( 0, nStartY
-1, 0 );
713 nPosX
= (long) ( nPosX
* HMM_PER_TWIPS
);
714 nPosY
= (long) ( nPosY
* HMM_PER_TWIPS
);
716 aPaperSize
.Width() *= 2; // limit OLE object to double of page size
717 aPaperSize
.Height() *= 2;
721 for (nCol
=nStartX
; nCol
<=nEndX
; nCol
++)
723 long nAdd
= rDestDoc
.GetColWidth( nCol
, 0 );
724 if ( bLimitToPageSize
&& nSizeX
+nAdd
> aPaperSize
.Width() && nSizeX
) // above limit?
728 for (SCROW nRow
=nStartY
; nRow
<=nEndY
; nRow
++)
730 long nAdd
= rDestDoc
.GetRowHeight( nRow
, 0 );
731 if ( bLimitToPageSize
&& nSizeY
+nAdd
> aPaperSize
.Height() && nSizeY
) // above limit?
735 nSizeX
= (long) ( nSizeX
* HMM_PER_TWIPS
);
736 nSizeY
= (long) ( nSizeY
* HMM_PER_TWIPS
);
738 // pDocSh->SetVisAreaSize( Size(nSizeX,nSizeY) );
740 Rectangle
aNewArea( Point(nPosX
,nPosY
), Size(nSizeX
,nSizeY
) );
741 //TODO/LATER: why twice?!
742 //pDocSh->SvInPlaceObject::SetVisArea( aNewArea );
743 pDocSh
->SetVisArea( aNewArea
);
745 pDocSh
->UpdateOle(&aViewData
, true);
747 //! SetDocumentModified?
748 if ( rDestDoc
.IsChartListenerCollectionNeedsUpdate() )
749 rDestDoc
.UpdateChartListenerCollection();
753 SfxObjectShell
* ScTransferObj::SetDrawClipDoc( bool bAnyOle
)
755 // update ScGlobal::xDrawClipDocShellRef
757 ScGlobal::xDrawClipDocShellRef
.Clear();
760 ScGlobal::xDrawClipDocShellRef
= new ScDocShell(SfxModelFlags::EMBEDDED_OBJECT
| SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS
); // there must be a ref
761 ScGlobal::xDrawClipDocShellRef
->DoInitNew();
762 return ScGlobal::xDrawClipDocShellRef
.get();
766 ScGlobal::xDrawClipDocShellRef
.Clear();
771 void ScTransferObj::StripRefs( ScDocument
* pDoc
,
772 SCCOL nStartX
, SCROW nStartY
, SCCOL nEndX
, SCROW nEndY
,
773 ScDocument
* pDestDoc
, SCCOL nSubX
, SCROW nSubY
)
778 OSL_ENSURE(nSubX
==0&&nSubY
==0, "can't move within the document");
781 // In a clipboard doc the data don't have to be on the first sheet
784 while (nSrcTab
<pDoc
->GetTableCount() && !pDoc
->HasTable(nSrcTab
))
787 while (nDestTab
<pDestDoc
->GetTableCount() && !pDestDoc
->HasTable(nDestTab
))
790 if (!pDoc
->HasTable(nSrcTab
) || !pDestDoc
->HasTable(nDestTab
))
792 OSL_FAIL("Sheet not found in ScTransferObj::StripRefs");
798 ScCellIterator
aIter( pDoc
, ScRange(nStartX
, nStartY
, nSrcTab
, nEndX
, nEndY
, nSrcTab
) );
799 for (bool bHas
= aIter
.first(); bHas
; bHas
= aIter
.next())
801 if (aIter
.getType() != CELLTYPE_FORMULA
)
804 ScFormulaCell
* pFCell
= aIter
.getFormulaCell();
806 ScDetectiveRefIter
aRefIter( pFCell
);
807 while ( !bOut
&& aRefIter
.GetNextRef( aRef
) )
809 if ( aRef
.aStart
.Tab() != nSrcTab
|| aRef
.aEnd
.Tab() != nSrcTab
||
810 aRef
.aStart
.Col() < nStartX
|| aRef
.aEnd
.Col() > nEndX
||
811 aRef
.aStart
.Row() < nStartY
|| aRef
.aEnd
.Row() > nEndY
)
816 SCCOL nCol
= aIter
.GetPos().Col() - nSubX
;
817 SCROW nRow
= aIter
.GetPos().Row() - nSubY
;
819 sal_uInt16 nErrCode
= pFCell
->GetErrCode();
820 ScAddress
aPos(nCol
, nRow
, nDestTab
);
823 if ( static_cast<const SvxHorJustifyItem
*>(pDestDoc
->GetAttr(
824 nCol
,nRow
,nDestTab
, ATTR_HOR_JUSTIFY
))->GetValue() ==
825 SVX_HOR_JUSTIFY_STANDARD
)
826 pDestDoc
->ApplyAttr( nCol
,nRow
,nDestTab
,
827 SvxHorJustifyItem(SVX_HOR_JUSTIFY_RIGHT
, ATTR_HOR_JUSTIFY
) );
829 ScSetStringParam aParam
;
830 aParam
.setTextInput();
831 pDestDoc
->SetString(aPos
, ScGlobal::GetErrorString(nErrCode
), &aParam
);
833 else if (pFCell
->IsValue())
835 pDestDoc
->SetValue(aPos
, pFCell
->GetValue());
839 OUString aStr
= pFCell
->GetString().getString();
840 if ( pFCell
->IsMultilineResult() )
842 ScFieldEditEngine
& rEngine
= pDestDoc
->GetEditEngine();
843 rEngine
.SetText(aStr
);
844 pDestDoc
->SetEditText(ScAddress(nCol
,nRow
,nDestTab
), rEngine
.CreateTextObject());
848 ScSetStringParam aParam
;
849 aParam
.setTextInput();
850 pDestDoc
->SetString(aPos
, aStr
, &aParam
);
859 class theScTransferUnoTunnelId
: public rtl::Static
< UnoTunnelIdInit
, theScTransferUnoTunnelId
> {};
862 const css::uno::Sequence
< sal_Int8
>& ScTransferObj::getUnoTunnelId()
864 return theScTransferUnoTunnelId::get().getSeq();
867 sal_Int64 SAL_CALL
ScTransferObj::getSomething( const css::uno::Sequence
< sal_Int8
>& rId
) throw( css::uno::RuntimeException
, std::exception
)
870 if( ( rId
.getLength() == 16 ) &&
871 ( 0 == memcmp( getUnoTunnelId().getConstArray(), rId
.getConstArray(), 16 ) ) )
873 nRet
= reinterpret_cast< sal_Int64
>( this );
876 nRet
= TransferableHelper::getSomething(rId
);
880 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */