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 "document.hxx"
40 #include "viewopti.hxx"
41 #include "editutil.hxx"
43 #include "formulacell.hxx"
44 #include "printfun.hxx"
45 #include "docfunc.hxx"
47 #include "dragdata.hxx"
48 #include "clipdata.hxx"
49 #include "clipparam.hxx"
51 #include <editeng/paperinf.hxx>
52 #include <editeng/sizeitem.hxx>
53 #include <svx/algitem.hxx>
54 #include <svl/intitem.hxx>
55 #include <svl/zforlist.hxx>
57 #include "markdata.hxx"
58 #include "stlpool.hxx"
59 #include "viewdata.hxx"
60 #include "dociter.hxx"
61 #include "cellsuno.hxx"
62 #include "stringutil.hxx"
63 #include "formulaiter.hxx"
64 #include <gridwin.hxx>
66 using namespace com::sun::star
;
68 #define SCTRANS_TYPE_IMPEX SotClipboardFormatId::STRING
69 #define SCTRANS_TYPE_EDIT_RTF SotClipboardFormatId::BITMAP
70 #define SCTRANS_TYPE_EDIT_BIN SotClipboardFormatId::GDIMETAFILE
71 #define SCTRANS_TYPE_EMBOBJ SotClipboardFormatId::PRIVATE
73 void ScTransferObj::GetAreaSize( ScDocument
* pDoc
, SCTAB nTab1
, SCTAB nTab2
, SCROW
& nRow
, SCCOL
& nCol
)
77 for( SCTAB nTab
= nTab1
; nTab
<= nTab2
; nTab
++ )
81 // GetPrintArea instead of GetCellArea - include drawing objects
82 if( pDoc
->GetPrintArea( nTab
, nLastCol
, nLastRow
) )
84 if( nLastCol
> nMaxCol
)
86 if( nLastRow
> nMaxRow
)
94 void ScTransferObj::PaintToDev( OutputDevice
* pDev
, ScDocument
* pDoc
, double nPrintFactor
,
95 const ScRange
& rBlock
, bool bMetaFile
)
101 Rectangle
aBound( aPoint
, pDev
->GetOutputSize() ); //! use size from clip area?
103 ScViewData
aViewData(NULL
,NULL
);
104 aViewData
.InitData( pDoc
);
106 aViewData
.SetTabNo( rBlock
.aEnd
.Tab() );
107 aViewData
.SetScreen( rBlock
.aStart
.Col(), rBlock
.aStart
.Row(),
108 rBlock
.aEnd
.Col(), rBlock
.aEnd
.Row() );
110 ScPrintFunc::DrawToDev( pDoc
, pDev
, nPrintFactor
, aBound
, &aViewData
, bMetaFile
);
113 ScTransferObj::ScTransferObj( ScDocument
* pClipDoc
, const TransferableObjectDescriptor
& rDesc
) :
119 nDragSourceFlags( 0 ),
120 bDragWasInternal( false ),
121 bUsedForLink( false ),
124 OSL_ENSURE(pDoc
->IsClipboard(), "wrong document");
126 // get aBlock from clipboard doc
132 pDoc
->GetClipStart( nCol1
, nRow1
);
133 pDoc
->GetClipArea( nCol2
, nRow2
, true ); // real source area - include filtered rows
134 nCol2
= sal::static_int_cast
<SCCOL
>( nCol2
+ nCol1
);
135 nRow2
= sal::static_int_cast
<SCROW
>( nRow2
+ nRow1
);
138 pDoc
->GetClipArea( nDummy
, nNonFiltered
, false );
139 bHasFiltered
= (nNonFiltered
< (nRow2
- nRow1
));
140 ++nNonFiltered
; // to get count instead of diff
145 for (SCTAB i
=0; i
< pDoc
->GetTableCount(); i
++)
146 if (pDoc
->HasTable(i
))
153 OSL_ENSURE(!bFirst
, "no sheet selected");
155 // only limit to used cells if whole sheet was marked
156 // (so empty cell areas can be copied)
157 if ( nCol2
>=MAXCOL
&& nRow2
>=MAXROW
)
161 GetAreaSize( pDoc
, nTab1
, nTab2
, nMaxRow
, nMaxCol
);
162 if( nMaxRow
< nRow2
)
164 if( nMaxCol
< nCol2
)
168 aBlock
= ScRange( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
169 nVisibleTab
= nTab1
; // valid table as default
171 Rectangle aMMRect
= pDoc
->GetMMRect( nCol1
,nRow1
, nCol2
,nRow2
, nTab1
);
172 aObjDesc
.maSize
= aMMRect
.GetSize();
173 PrepareOLE( aObjDesc
);
176 ScTransferObj::~ScTransferObj()
178 SolarMutexGuard aSolarGuard
;
180 ScModule
* pScMod
= SC_MOD();
181 if ( pScMod
->GetClipData().pCellClipboard
== this )
183 OSL_FAIL("ScTransferObj wasn't released");
184 pScMod
->SetClipObject( NULL
, NULL
);
186 if ( pScMod
->GetDragData().pCellTransfer
== this )
188 OSL_FAIL("ScTransferObj wasn't released");
189 pScMod
->ResetDragObject();
192 delete pDoc
; // ScTransferObj is owner of clipboard document
194 aDocShellRef
.Clear(); // before releasing the mutex
196 aDrawPersistRef
.Clear(); // after the model
200 ScTransferObj
* ScTransferObj::GetOwnClipboard( vcl::Window
* pUIWin
)
202 ScTransferObj
* pObj
= SC_MOD()->GetClipData().pCellClipboard
;
203 if ( pObj
&& pUIWin
)
205 // check formats to see if pObj is really in the system clipboard
207 // pUIWin is NULL when called from core (IsClipboardSource),
208 // in that case don't access the system clipboard, because the call
209 // may be from other clipboard operations (like flushing, #86059#)
211 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pUIWin
) );
212 if ( !aDataHelper
.HasFormat( SotClipboardFormatId::DIF
) )
214 // OSL_FAIL("ScTransferObj wasn't released");
221 void ScTransferObj::AddSupportedFormats()
223 AddFormat( SotClipboardFormatId::EMBED_SOURCE
);
224 AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR
);
225 AddFormat( SotClipboardFormatId::GDIMETAFILE
);
226 AddFormat( SotClipboardFormatId::PNG
);
227 AddFormat( SotClipboardFormatId::BITMAP
);
229 // ScImportExport formats
230 AddFormat( SotClipboardFormatId::HTML
);
231 AddFormat( SotClipboardFormatId::SYLK
);
232 AddFormat( SotClipboardFormatId::LINK
);
233 AddFormat( SotClipboardFormatId::DIF
);
234 AddFormat( SotClipboardFormatId::STRING
);
236 AddFormat( SotClipboardFormatId::RTF
);
237 if ( aBlock
.aStart
== aBlock
.aEnd
)
238 AddFormat( SotClipboardFormatId::EDITENGINE
);
241 bool ScTransferObj::GetData( const datatransfer::DataFlavor
& rFlavor
, const OUString
& /*rDestDoc*/ )
243 SotClipboardFormatId nFormat
= SotExchange::GetFormat( rFlavor
);
246 if( HasFormat( nFormat
) )
248 if ( nFormat
== SotClipboardFormatId::LINKSRCDESCRIPTOR
|| nFormat
== SotClipboardFormatId::OBJECTDESCRIPTOR
)
250 bOK
= SetTransferableObjectDescriptor( aObjDesc
, rFlavor
);
252 else if ( ( nFormat
== SotClipboardFormatId::RTF
|| nFormat
== SotClipboardFormatId::EDITENGINE
) &&
253 aBlock
.aStart
== aBlock
.aEnd
)
255 // RTF from a single cell is handled by EditEngine
257 SCCOL nCol
= aBlock
.aStart
.Col();
258 SCROW nRow
= aBlock
.aStart
.Row();
259 SCTAB nTab
= aBlock
.aStart
.Tab();
260 ScAddress
aPos(nCol
, nRow
, nTab
);
262 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
263 ScTabEditEngine
aEngine( *pPattern
, pDoc
->GetEditPool() );
264 if (pDoc
->GetCellType(aPos
) == CELLTYPE_EDIT
)
266 const EditTextObject
* pObj
= pDoc
->GetEditText(aPos
);
268 aEngine
.SetText(*pObj
);
272 OUString aText
= pDoc
->GetString(nCol
, nRow
, nTab
);
273 if (!aText
.isEmpty())
274 aEngine
.SetText(aText
);
277 bOK
= SetObject( &aEngine
,
278 (nFormat
== SotClipboardFormatId::RTF
) ? SCTRANS_TYPE_EDIT_RTF
: SCTRANS_TYPE_EDIT_BIN
,
281 else if ( ScImportExport::IsFormatSupported( nFormat
) || nFormat
== SotClipboardFormatId::RTF
)
283 // if this transfer object was used to create a DDE link, filtered rows
284 // have to be included for subsequent calls (to be consistent with link data)
285 if ( nFormat
== SotClipboardFormatId::LINK
)
288 bool bIncludeFiltered
= pDoc
->IsCutMode() || bUsedForLink
;
290 bool bReduceBlockFormat
= nFormat
== SotClipboardFormatId::HTML
|| nFormat
== SotClipboardFormatId::RTF
;
291 ScRange aReducedBlock
= aBlock
;
292 if (bReduceBlockFormat
&& (aBlock
.aEnd
.Col() == MAXCOL
|| aBlock
.aEnd
.Row() == MAXROW
) && aBlock
.aStart
.Tab() == aBlock
.aEnd
.Tab())
294 bool bShrunk
= false;
295 //shrink the area to allow pasting to external applications
296 SCCOL aStartCol
= aReducedBlock
.aStart
.Col();
297 SCROW aStartRow
= aReducedBlock
.aStart
.Row();
298 SCCOL aEndCol
= aReducedBlock
.aEnd
.Col();
299 SCROW aEndRow
= aReducedBlock
.aEnd
.Row();
300 pDoc
->ShrinkToUsedDataArea( bShrunk
, aReducedBlock
.aStart
.Tab(), aStartCol
, aStartRow
, aEndCol
, aEndRow
, false);
301 aReducedBlock
= ScRange(aStartCol
, aStartRow
, aReducedBlock
.aStart
.Tab(), aEndCol
, aEndRow
, aReducedBlock
.aEnd
.Tab());
304 ScImportExport
aObj( pDoc
, aReducedBlock
);
305 ScExportTextOptions
aTextOptions(ScExportTextOptions::None
, 0, true);
308 // For a DDE link, convert line breaks and separators to space.
309 aTextOptions
.meNewlineConversion
= ScExportTextOptions::ToSpace
;
310 aTextOptions
.mcSeparatorConvertTo
= ' ';
311 aTextOptions
.mbAddQuotes
= false;
313 aObj
.SetExportTextOptions(aTextOptions
);
314 aObj
.SetFormulas( pDoc
->GetViewOptions().GetOption( VOPT_FORMULAS
) );
315 aObj
.SetIncludeFiltered( bIncludeFiltered
);
317 // DataType depends on format type:
319 if ( rFlavor
.DataType
.equals( ::cppu::UnoType
<OUString
>::get() ) )
322 if ( aObj
.ExportString( aString
, nFormat
) )
323 bOK
= SetString( aString
, rFlavor
);
325 else if ( rFlavor
.DataType
.equals( cppu::UnoType
<uno::Sequence
< sal_Int8
>>::get() ) )
327 // SetObject converts a stream into a Int8-Sequence
328 bOK
= SetObject( &aObj
, SCTRANS_TYPE_IMPEX
, rFlavor
);
332 OSL_FAIL("unknown DataType");
335 else if ( nFormat
== SotClipboardFormatId::BITMAP
|| nFormat
== SotClipboardFormatId::PNG
)
337 Rectangle aMMRect
= pDoc
->GetMMRect( aBlock
.aStart
.Col(), aBlock
.aStart
.Row(),
338 aBlock
.aEnd
.Col(), aBlock
.aEnd
.Row(),
339 aBlock
.aStart
.Tab() );
340 ScopedVclPtrInstance
< VirtualDevice
> pVirtDev
;
341 pVirtDev
->SetOutputSizePixel( pVirtDev
->LogicToPixel( aMMRect
.GetSize(), MAP_100TH_MM
) );
343 PaintToDev( pVirtDev
, pDoc
, 1.0, aBlock
, false );
345 pVirtDev
->SetMapMode( MapMode( MAP_PIXEL
) );
346 Bitmap aBmp
= pVirtDev
->GetBitmap( Point(), pVirtDev
->GetOutputSize() );
347 bOK
= SetBitmapEx( aBmp
, rFlavor
);
349 else if ( nFormat
== SotClipboardFormatId::GDIMETAFILE
)
351 // #i123405# Do not limit visual size calculation for metafile creation.
352 // It seems unlikely that removing the limitation causes problems since
353 // metafile creation means that no real pixel device in the needed size is
357 SfxObjectShell
* pEmbObj
= aDocShellRef
;
359 // like SvEmbeddedTransfer::GetData:
361 ScopedVclPtrInstance
< VirtualDevice
> pVDev
;
362 MapMode
aMapMode( pEmbObj
->GetMapUnit() );
363 Rectangle
aVisArea( pEmbObj
->GetVisArea( ASPECT_CONTENT
) );
365 pVDev
->EnableOutput( false );
366 pVDev
->SetMapMode( aMapMode
);
367 aMtf
.SetPrefSize( aVisArea
.GetSize() );
368 aMtf
.SetPrefMapMode( aMapMode
);
369 aMtf
.Record( pVDev
);
371 pEmbObj
->DoDraw( pVDev
, Point(), aVisArea
.GetSize(), JobSetup(), ASPECT_CONTENT
);
376 bOK
= SetGDIMetaFile( aMtf
, rFlavor
);
378 else if ( nFormat
== SotClipboardFormatId::EMBED_SOURCE
)
380 //TODO/LATER: differentiate between formats?!
381 // #i123405# Do limit visual size calculation to PageSize
382 InitDocShell(true); // set aDocShellRef
384 SfxObjectShell
* pEmbObj
= aDocShellRef
;
385 bOK
= SetObject( pEmbObj
, SCTRANS_TYPE_EMBOBJ
, rFlavor
);
391 bool ScTransferObj::WriteObject( tools::SvRef
<SotStorageStream
>& rxOStm
, void* pUserObject
, SotClipboardFormatId nUserObjectId
,
392 const datatransfer::DataFlavor
& rFlavor
)
394 // called from SetObject, put data into stream
397 switch (nUserObjectId
)
399 case SCTRANS_TYPE_IMPEX
:
401 ScImportExport
* pImpEx
= static_cast<ScImportExport
*>(pUserObject
);
403 SotClipboardFormatId nFormat
= SotExchange::GetFormat( rFlavor
);
404 // mba: no BaseURL for data exchange
405 if ( pImpEx
->ExportStream( *rxOStm
, OUString(), nFormat
) )
406 bRet
= ( rxOStm
->GetError() == ERRCODE_NONE
);
410 case SCTRANS_TYPE_EDIT_RTF
:
411 case SCTRANS_TYPE_EDIT_BIN
:
413 ScTabEditEngine
* pEngine
= static_cast<ScTabEditEngine
*>(pUserObject
);
414 if ( nUserObjectId
== SCTRANS_TYPE_EDIT_RTF
)
416 pEngine
->Write( *rxOStm
, EE_FORMAT_RTF
);
417 bRet
= ( rxOStm
->GetError() == ERRCODE_NONE
);
421 // can't use Write for EditEngine format because that would
422 // write old format without support for unicode characters.
423 // Get the data from the EditEngine's transferable instead.
425 sal_Int32 nParCnt
= pEngine
->GetParagraphCount();
428 ESelection
aSel( 0, 0, nParCnt
-1, pEngine
->GetTextLen(nParCnt
-1) );
430 uno::Reference
<datatransfer::XTransferable
> xEditTrans
= pEngine
->CreateTransferable( aSel
);
431 TransferableDataHelper
aEditHelper( xEditTrans
);
433 bRet
= aEditHelper
.GetSotStorageStream( rFlavor
, rxOStm
);
438 case SCTRANS_TYPE_EMBOBJ
:
441 SfxObjectShell
* pEmbObj
= static_cast<SfxObjectShell
*>(pUserObject
);
442 ::utl::TempFile aTempFile
;
443 aTempFile
.EnableKillingFile();
444 uno::Reference
< embed::XStorage
> xWorkStore
=
445 ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile
.GetURL(), embed::ElementModes::READWRITE
);
447 // write document storage
448 pEmbObj
->SetupStorage( xWorkStore
, SOFFICE_FILEFORMAT_CURRENT
, false, false );
450 // mba: no relative URLs for clipboard!
451 SfxMedium
aMedium( xWorkStore
, OUString() );
452 bRet
= pEmbObj
->DoSaveObjectAs( aMedium
, false );
453 pEmbObj
->DoSaveCompleted();
455 uno::Reference
< embed::XTransactedObject
> xTransact( xWorkStore
, uno::UNO_QUERY
);
456 if ( xTransact
.is() )
459 SvStream
* pSrcStm
= ::utl::UcbStreamHelper::CreateStream( aTempFile
.GetURL(), StreamMode::READ
);
462 rxOStm
->SetBufferSize( 0xff00 );
463 rxOStm
->WriteStream( *pSrcStm
);
469 xWorkStore
->dispose();
470 xWorkStore
= uno::Reference
< embed::XStorage
>();
476 OSL_FAIL("unknown object id");
481 void ScTransferObj::ObjectReleased()
483 ScModule
* pScMod
= SC_MOD();
484 if ( pScMod
->GetClipData().pCellClipboard
== this )
485 pScMod
->SetClipObject( NULL
, NULL
);
487 TransferableHelper::ObjectReleased();
490 void ScTransferObj::DragFinished( sal_Int8 nDropAction
)
492 if ( nDropAction
== DND_ACTION_MOVE
&& !bDragWasInternal
&& !(nDragSourceFlags
& SC_DROP_NAVIGATOR
) )
494 // move: delete source data
495 ScDocShell
* pSourceSh
= GetSourceDocShell();
498 ScMarkData aMarkData
= GetSourceMarkData();
499 // external drag&drop doesn't copy objects, so they also aren't deleted:
500 // bApi=TRUE, don't show error messages from drag&drop
501 pSourceSh
->GetDocFunc().DeleteContents( aMarkData
, IDF_ALL
& ~IDF_OBJECTS
, true, true );
505 ScModule
* pScMod
= SC_MOD();
506 if ( pScMod
->GetDragData().pCellTransfer
== this )
507 pScMod
->ResetDragObject();
509 xDragSourceRanges
= NULL
; // don't keep source after dropping
511 TransferableHelper::DragFinished( nDropAction
);
514 void ScTransferObj::SetDragHandlePos( SCCOL nX
, SCROW nY
)
520 void ScTransferObj::SetVisibleTab( SCTAB nNew
)
525 void ScTransferObj::SetDrawPersist( const SfxObjectShellRef
& rRef
)
527 aDrawPersistRef
= rRef
;
530 void ScTransferObj::SetDragSource( ScDocShell
* pSourceShell
, const ScMarkData
& rMark
)
533 rMark
.FillRangeListWithMarks( &aRanges
, false );
534 xDragSourceRanges
= new ScCellRangesObj( pSourceShell
, aRanges
);
537 void ScTransferObj::SetDragSourceFlags( sal_uInt16 nFlags
)
539 nDragSourceFlags
= nFlags
;
542 void ScTransferObj::SetDragWasInternal()
544 bDragWasInternal
= true;
547 void ScTransferObj::SetUseInApi( bool bSet
)
552 ScDocument
* ScTransferObj::GetSourceDocument()
554 ScDocShell
* pSourceDocSh
= GetSourceDocShell();
556 return &pSourceDocSh
->GetDocument();
560 ScDocShell
* ScTransferObj::GetSourceDocShell()
562 ScCellRangesBase
* pRangesObj
= ScCellRangesBase::getImplementation( xDragSourceRanges
);
564 return pRangesObj
->GetDocShell();
566 return NULL
; // none set
569 ScMarkData
ScTransferObj::GetSourceMarkData()
571 ScMarkData aMarkData
;
572 ScCellRangesBase
* pRangesObj
= ScCellRangesBase::getImplementation( xDragSourceRanges
);
575 const ScRangeList
& rRanges
= pRangesObj
->GetRangeList();
576 aMarkData
.MarkFromRangeList( rRanges
, false );
581 // initialize aDocShellRef with a live document from the ClipDoc
583 // #i123405# added parameter to allow size calculation without limitation
584 // to PageSize, e.g. used for Metafile creation for clipboard.
586 void ScTransferObj::InitDocShell(bool bLimitToPageSize
)
588 if ( !aDocShellRef
.Is() )
590 ScDocShell
* pDocSh
= new ScDocShell
;
591 aDocShellRef
= pDocSh
; // ref must be there before InitNew
593 pDocSh
->DoInitNew(NULL
);
595 ScDocument
& rDestDoc
= pDocSh
->GetDocument();
596 ScMarkData aDestMark
;
597 aDestMark
.SelectTable( 0, true );
599 rDestDoc
.SetDocOptions( pDoc
->GetDocOptions() ); // #i42666#
602 pDoc
->GetName( aBlock
.aStart
.Tab(), aTabName
);
603 rDestDoc
.RenameTab( 0, aTabName
, false ); // no UpdateRef (empty)
605 rDestDoc
.CopyStdStylesFrom( pDoc
);
607 SCCOL nStartX
= aBlock
.aStart
.Col();
608 SCROW nStartY
= aBlock
.aStart
.Row();
609 SCCOL nEndX
= aBlock
.aEnd
.Col();
610 SCROW nEndY
= aBlock
.aEnd
.Row();
613 // (must be copied before CopyFromClip, for drawing objects)
616 SCTAB nSrcTab
= aBlock
.aStart
.Tab();
617 rDestDoc
.SetLayoutRTL(0, pDoc
->IsLayoutRTL(nSrcTab
));
618 for (nCol
=nStartX
; nCol
<=nEndX
; nCol
++)
619 if ( pDoc
->ColHidden(nCol
, nSrcTab
) )
620 rDestDoc
.ShowCol( nCol
, 0, false );
622 rDestDoc
.SetColWidth( nCol
, 0, pDoc
->GetColWidth( nCol
, nSrcTab
) );
624 for (SCROW nRow
= nStartY
; nRow
<= nEndY
; ++nRow
)
626 if ( pDoc
->RowHidden(nRow
, nSrcTab
) )
627 rDestDoc
.ShowRow( nRow
, 0, false );
630 rDestDoc
.SetRowHeight( nRow
, 0, pDoc
->GetOriginalHeight( nRow
, nSrcTab
) );
632 // if height was set manually, that flag has to be copied, too
633 bool bManual
= pDoc
->IsManualRowHeight(nRow
, nSrcTab
);
634 rDestDoc
.SetManualHeight(nRow
, nRow
, 0, bManual
);
638 if (pDoc
->GetDrawLayer() || pDoc
->HasNotes())
639 pDocSh
->MakeDrawLayer();
641 // cell range is copied to the original position, but on the first sheet
642 // -> bCutMode must be set
643 // pDoc is always a Clipboard-document
645 ScRange
aDestRange( nStartX
,nStartY
,0, nEndX
,nEndY
,0 );
646 bool bWasCut
= pDoc
->IsCutMode();
648 pDoc
->SetClipArea( aDestRange
, true ); // Cut
649 rDestDoc
.CopyFromClip( aDestRange
, aDestMark
, IDF_ALL
, NULL
, pDoc
, false );
650 pDoc
->SetClipArea( aDestRange
, bWasCut
);
652 StripRefs( pDoc
, nStartX
,nStartY
, nEndX
,nEndY
, &rDestDoc
, 0,0 );
654 ScRange aMergeRange
= aDestRange
;
655 rDestDoc
.ExtendMerge( aMergeRange
, true );
657 pDoc
->CopyDdeLinks( &rDestDoc
); // copy values of DDE Links
659 // page format (grid etc) and page size (maximum size for ole object)
661 Size aPaperSize
= SvxPaperInfo::GetPaperSize( PAPER_A4
); // Twips
662 ScStyleSheetPool
* pStylePool
= pDoc
->GetStyleSheetPool();
663 OUString aStyleName
= pDoc
->GetPageStyle( aBlock
.aStart
.Tab() );
664 SfxStyleSheetBase
* pStyleSheet
= pStylePool
->Find( aStyleName
, SFX_STYLE_FAMILY_PAGE
);
667 const SfxItemSet
& rSourceSet
= pStyleSheet
->GetItemSet();
668 aPaperSize
= static_cast<const SvxSizeItem
&>( rSourceSet
.Get(ATTR_PAGE_SIZE
)).GetSize();
670 // CopyStyleFrom kopiert SetItems mit richtigem Pool
671 ScStyleSheetPool
* pDestPool
= rDestDoc
.GetStyleSheetPool();
672 pDestPool
->CopyStyleFrom( pStylePool
, aStyleName
, SFX_STYLE_FAMILY_PAGE
);
675 ScViewData
aViewData( pDocSh
, NULL
);
676 aViewData
.SetScreen( nStartX
,nStartY
, nEndX
,nEndY
);
677 aViewData
.SetCurX( nStartX
);
678 aViewData
.SetCurY( nStartY
);
680 rDestDoc
.SetViewOptions( pDoc
->GetViewOptions() );
683 //! get while copying sizes
688 for (nCol
=0; nCol
<nStartX
; nCol
++)
689 nPosX
+= rDestDoc
.GetColWidth( nCol
, 0 );
690 nPosY
+= rDestDoc
.GetRowHeight( 0, nStartY
-1, 0 );
691 nPosX
= (long) ( nPosX
* HMM_PER_TWIPS
);
692 nPosY
= (long) ( nPosY
* HMM_PER_TWIPS
);
694 aPaperSize
.Width() *= 2; // limit OLE object to double of page size
695 aPaperSize
.Height() *= 2;
699 for (nCol
=nStartX
; nCol
<=nEndX
; nCol
++)
701 long nAdd
= rDestDoc
.GetColWidth( nCol
, 0 );
702 if ( bLimitToPageSize
&& nSizeX
+nAdd
> aPaperSize
.Width() && nSizeX
) // above limit?
706 for (SCROW nRow
=nStartY
; nRow
<=nEndY
; nRow
++)
708 long nAdd
= rDestDoc
.GetRowHeight( nRow
, 0 );
709 if ( bLimitToPageSize
&& nSizeY
+nAdd
> aPaperSize
.Height() && nSizeY
) // above limit?
713 nSizeX
= (long) ( nSizeX
* HMM_PER_TWIPS
);
714 nSizeY
= (long) ( nSizeY
* HMM_PER_TWIPS
);
716 // pDocSh->SetVisAreaSize( Size(nSizeX,nSizeY) );
718 Rectangle
aNewArea( Point(nPosX
,nPosY
), Size(nSizeX
,nSizeY
) );
719 //TODO/LATER: why twice?!
720 //pDocSh->SvInPlaceObject::SetVisArea( aNewArea );
721 pDocSh
->SetVisArea( aNewArea
);
723 pDocSh
->UpdateOle(&aViewData
, true);
725 //! SetDocumentModified?
726 if ( rDestDoc
.IsChartListenerCollectionNeedsUpdate() )
727 rDestDoc
.UpdateChartListenerCollection();
731 SfxObjectShell
* ScTransferObj::SetDrawClipDoc( bool bAnyOle
)
733 // update ScGlobal::pDrawClipDocShellRef
735 delete ScGlobal::pDrawClipDocShellRef
;
738 ScGlobal::pDrawClipDocShellRef
=
739 new ScDocShellRef(new ScDocShell(SfxModelFlags::EMBEDDED_OBJECT
| SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS
)); // there must be a ref
740 (*ScGlobal::pDrawClipDocShellRef
)->DoInitNew(NULL
);
741 return *ScGlobal::pDrawClipDocShellRef
;
745 ScGlobal::pDrawClipDocShellRef
= NULL
;
750 void ScTransferObj::StripRefs( ScDocument
* pDoc
,
751 SCCOL nStartX
, SCROW nStartY
, SCCOL nEndX
, SCROW nEndY
,
752 ScDocument
* pDestDoc
, SCCOL nSubX
, SCROW nSubY
)
757 OSL_ENSURE(nSubX
==0&&nSubY
==0, "can't move within the document");
760 // In a clipboard doc the data don't have to be on the first sheet
763 while (nSrcTab
<pDoc
->GetTableCount() && !pDoc
->HasTable(nSrcTab
))
766 while (nDestTab
<pDestDoc
->GetTableCount() && !pDestDoc
->HasTable(nDestTab
))
769 if (!pDoc
->HasTable(nSrcTab
) || !pDestDoc
->HasTable(nDestTab
))
771 OSL_FAIL("Sheet not found in ScTransferObj::StripRefs");
777 ScCellIterator
aIter( pDoc
, ScRange(nStartX
, nStartY
, nSrcTab
, nEndX
, nEndY
, nSrcTab
) );
778 for (bool bHas
= aIter
.first(); bHas
; bHas
= aIter
.next())
780 if (aIter
.getType() != CELLTYPE_FORMULA
)
783 ScFormulaCell
* pFCell
= aIter
.getFormulaCell();
785 ScDetectiveRefIter
aRefIter( pFCell
);
786 while ( !bOut
&& aRefIter
.GetNextRef( aRef
) )
788 if ( aRef
.aStart
.Tab() != nSrcTab
|| aRef
.aEnd
.Tab() != nSrcTab
||
789 aRef
.aStart
.Col() < nStartX
|| aRef
.aEnd
.Col() > nEndX
||
790 aRef
.aStart
.Row() < nStartY
|| aRef
.aEnd
.Row() > nEndY
)
795 SCCOL nCol
= aIter
.GetPos().Col() - nSubX
;
796 SCROW nRow
= aIter
.GetPos().Row() - nSubY
;
798 sal_uInt16 nErrCode
= pFCell
->GetErrCode();
799 ScAddress
aPos(nCol
, nRow
, nDestTab
);
802 if ( static_cast<const SvxHorJustifyItem
*>(pDestDoc
->GetAttr(
803 nCol
,nRow
,nDestTab
, ATTR_HOR_JUSTIFY
))->GetValue() ==
804 SVX_HOR_JUSTIFY_STANDARD
)
805 pDestDoc
->ApplyAttr( nCol
,nRow
,nDestTab
,
806 SvxHorJustifyItem(SVX_HOR_JUSTIFY_RIGHT
, ATTR_HOR_JUSTIFY
) );
808 ScSetStringParam aParam
;
809 aParam
.setTextInput();
810 pDestDoc
->SetString(aPos
, ScGlobal::GetErrorString(nErrCode
), &aParam
);
812 else if (pFCell
->IsValue())
814 pDestDoc
->SetValue(aPos
, pFCell
->GetValue());
818 OUString aStr
= pFCell
->GetString().getString();
819 if ( pFCell
->IsMultilineResult() )
821 ScFieldEditEngine
& rEngine
= pDestDoc
->GetEditEngine();
822 rEngine
.SetText(aStr
);
823 pDestDoc
->SetEditText(ScAddress(nCol
,nRow
,nDestTab
), rEngine
.CreateTextObject());
827 ScSetStringParam aParam
;
828 aParam
.setTextInput();
829 pDestDoc
->SetString(aPos
, aStr
, &aParam
);
838 class theScTransferUnoTunnelId
: public rtl::Static
< UnoTunnelIdInit
, theScTransferUnoTunnelId
> {};
841 const com::sun::star::uno::Sequence
< sal_Int8
>& ScTransferObj::getUnoTunnelId()
843 return theScTransferUnoTunnelId::get().getSeq();
846 sal_Int64 SAL_CALL
ScTransferObj::getSomething( const com::sun::star::uno::Sequence
< sal_Int8
>& rId
) throw( com::sun::star::uno::RuntimeException
, std::exception
)
849 if( ( rId
.getLength() == 16 ) &&
850 ( 0 == memcmp( getUnoTunnelId().getConstArray(), rId
.getConstArray(), 16 ) ) )
852 nRet
= reinterpret_cast< sal_Int64
>( this );
855 nRet
= TransferableHelper::getSomething(rId
);
859 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */