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>
25 #include <com/sun/star/uno/Sequence.hxx>
26 #include <com/sun/star/embed/XTransactedObject.hpp>
28 #include <unotools/tempfile.hxx>
29 #include <unotools/ucbstreamhelper.hxx>
30 #include <comphelper/storagehelper.hxx>
31 #include <comphelper/servicehelper.hxx>
32 #include <sot/storage.hxx>
33 #include <vcl/svapp.hxx>
34 #include <vcl/virdev.hxx>
35 #include <osl/mutex.hxx>
36 #include <sfx2/app.hxx>
37 #include <sfx2/docfile.hxx>
39 #include "transobj.hxx"
40 #include "document.hxx"
41 #include "viewopti.hxx"
42 #include "editutil.hxx"
44 #include "formulacell.hxx"
45 #include "printfun.hxx"
46 #include "docfunc.hxx"
48 #include "dragdata.hxx"
49 #include "clipdata.hxx"
50 #include "clipparam.hxx"
53 #include <editeng/paperinf.hxx>
54 #include <editeng/sizeitem.hxx>
55 #include <svx/algitem.hxx>
56 #include <svl/intitem.hxx>
57 #include <svl/zforlist.hxx>
59 #include "markdata.hxx"
60 #include "stlpool.hxx"
61 #include "viewdata.hxx"
62 #include "dociter.hxx"
63 #include "cellsuno.hxx"
64 #include "stringutil.hxx"
65 #include "formulaiter.hxx"
67 using namespace com::sun::star
;
69 // -----------------------------------------------------------------------
71 #define SCTRANS_TYPE_IMPEX 1
72 #define SCTRANS_TYPE_EDIT_RTF 2
73 #define SCTRANS_TYPE_EDIT_BIN 3
74 #define SCTRANS_TYPE_EMBOBJ 4
76 // -----------------------------------------------------------------------
78 void ScTransferObj::GetAreaSize( ScDocument
* pDoc
, SCTAB nTab1
, SCTAB nTab2
, SCROW
& nRow
, SCCOL
& nCol
)
82 for( SCTAB nTab
= nTab1
; nTab
<= nTab2
; nTab
++ )
86 // GetPrintArea instead of GetCellArea - include drawing objects
87 if( pDoc
->GetPrintArea( nTab
, nLastCol
, nLastRow
) )
89 if( nLastCol
> nMaxCol
)
91 if( nLastRow
> nMaxRow
)
99 void ScTransferObj::PaintToDev( OutputDevice
* pDev
, ScDocument
* pDoc
, double nPrintFactor
,
100 const ScRange
& rBlock
, sal_Bool bMetaFile
)
106 Rectangle
aBound( aPoint
, pDev
->GetOutputSize() ); //! use size from clip area?
108 ScViewData
aViewData(NULL
,NULL
);
109 aViewData
.InitData( pDoc
);
111 aViewData
.SetTabNo( rBlock
.aEnd
.Tab() );
112 aViewData
.SetScreen( rBlock
.aStart
.Col(), rBlock
.aStart
.Row(),
113 rBlock
.aEnd
.Col(), rBlock
.aEnd
.Row() );
115 ScPrintFunc::DrawToDev( pDoc
, pDev
, nPrintFactor
, aBound
, &aViewData
, bMetaFile
);
118 // -----------------------------------------------------------------------
120 ScTransferObj::ScTransferObj( ScDocument
* pClipDoc
, const TransferableObjectDescriptor
& rDesc
) :
125 nDragSourceFlags( 0 ),
126 bDragWasInternal( false ),
127 bUsedForLink( false ),
130 OSL_ENSURE(pDoc
->IsClipboard(), "wrong document");
133 // get aBlock from clipboard doc
140 pDoc
->GetClipStart( nCol1
, nRow1
);
141 pDoc
->GetClipArea( nCol2
, nRow2
, true ); // real source area - include filtered rows
142 nCol2
= sal::static_int_cast
<SCCOL
>( nCol2
+ nCol1
);
143 nRow2
= sal::static_int_cast
<SCROW
>( nRow2
+ nRow1
);
146 pDoc
->GetClipArea( nDummy
, nNonFiltered
, false );
147 bHasFiltered
= (nNonFiltered
< (nRow2
- nRow1
));
148 ++nNonFiltered
; // to get count instead of diff
153 for (SCTAB i
=0; i
< pDoc
->GetTableCount(); i
++)
154 if (pDoc
->HasTable(i
))
161 OSL_ENSURE(!bFirst
, "no sheet selected");
163 // only limit to used cells if whole sheet was marked
164 // (so empty cell areas can be copied)
165 if ( nCol2
>=MAXCOL
&& nRow2
>=MAXROW
)
169 GetAreaSize( pDoc
, nTab1
, nTab2
, nMaxRow
, nMaxCol
);
170 if( nMaxRow
< nRow2
)
172 if( nMaxCol
< nCol2
)
176 aBlock
= ScRange( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
177 nVisibleTab
= nTab1
; // valid table as default
179 Rectangle aMMRect
= pDoc
->GetMMRect( nCol1
,nRow1
, nCol2
,nRow2
, nTab1
);
180 aObjDesc
.maSize
= aMMRect
.GetSize();
181 PrepareOLE( aObjDesc
);
184 ScTransferObj::~ScTransferObj()
186 SolarMutexGuard aSolarGuard
;
188 ScModule
* pScMod
= SC_MOD();
189 if ( pScMod
->GetClipData().pCellClipboard
== this )
191 OSL_FAIL("ScTransferObj wasn't released");
192 pScMod
->SetClipObject( NULL
, NULL
);
194 if ( pScMod
->GetDragData().pCellTransfer
== this )
196 OSL_FAIL("ScTransferObj wasn't released");
197 pScMod
->ResetDragObject();
200 delete pDoc
; // ScTransferObj is owner of clipboard document
202 aDocShellRef
.Clear(); // before releasing the mutex
204 aDrawPersistRef
.Clear(); // after the model
208 ScTransferObj
* ScTransferObj::GetOwnClipboard( Window
* pUIWin
)
210 ScTransferObj
* pObj
= SC_MOD()->GetClipData().pCellClipboard
;
211 if ( pObj
&& pUIWin
)
213 // check formats to see if pObj is really in the system clipboard
215 // pUIWin is NULL when called from core (IsClipboardSource),
216 // in that case don't access the system clipboard, because the call
217 // may be from other clipboard operations (like flushing, #86059#)
219 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pUIWin
) );
220 if ( !aDataHelper
.HasFormat( SOT_FORMATSTR_ID_DIF
) )
222 // OSL_FAIL("ScTransferObj wasn't released");
229 void ScTransferObj::AddSupportedFormats()
231 AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE
);
232 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
);
233 AddFormat( SOT_FORMAT_GDIMETAFILE
);
234 AddFormat( SOT_FORMAT_BITMAP
);
236 // ScImportExport formats
237 AddFormat( SOT_FORMATSTR_ID_HTML
);
238 AddFormat( SOT_FORMATSTR_ID_SYLK
);
239 AddFormat( SOT_FORMATSTR_ID_LINK
);
240 AddFormat( SOT_FORMATSTR_ID_DIF
);
241 AddFormat( SOT_FORMAT_STRING
);
243 AddFormat( SOT_FORMAT_RTF
);
244 if ( aBlock
.aStart
== aBlock
.aEnd
)
245 AddFormat( SOT_FORMATSTR_ID_EDITENGINE
);
248 sal_Bool
ScTransferObj::GetData( const datatransfer::DataFlavor
& rFlavor
)
250 sal_uInt32 nFormat
= SotExchange::GetFormat( rFlavor
);
253 if( HasFormat( nFormat
) )
255 if ( nFormat
== SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR
|| nFormat
== SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
)
257 bOK
= SetTransferableObjectDescriptor( aObjDesc
, rFlavor
);
259 else if ( ( nFormat
== SOT_FORMAT_RTF
|| nFormat
== SOT_FORMATSTR_ID_EDITENGINE
) &&
260 aBlock
.aStart
== aBlock
.aEnd
)
262 // RTF from a single cell is handled by EditEngine
264 SCCOL nCol
= aBlock
.aStart
.Col();
265 SCROW nRow
= aBlock
.aStart
.Row();
266 SCTAB nTab
= aBlock
.aStart
.Tab();
267 ScAddress
aPos(nCol
, nRow
, nTab
);
269 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
270 ScTabEditEngine
aEngine( *pPattern
, pDoc
->GetEditPool() );
271 if (pDoc
->GetCellType(aPos
) == CELLTYPE_EDIT
)
273 const EditTextObject
* pObj
= pDoc
->GetEditText(aPos
);
275 aEngine
.SetText(*pObj
);
279 OUString aText
= pDoc
->GetString(nCol
, nRow
, nTab
);
280 if (!aText
.isEmpty())
281 aEngine
.SetText(aText
);
284 bOK
= SetObject( &aEngine
,
285 (nFormat
== FORMAT_RTF
) ? SCTRANS_TYPE_EDIT_RTF
: SCTRANS_TYPE_EDIT_BIN
,
288 else if ( ScImportExport::IsFormatSupported( nFormat
) || nFormat
== SOT_FORMAT_RTF
)
290 // if this transfer object was used to create a DDE link, filtered rows
291 // have to be included for subsequent calls (to be consistent with link data)
292 if ( nFormat
== SOT_FORMATSTR_ID_LINK
)
295 bool bIncludeFiltered
= pDoc
->IsCutMode() || bUsedForLink
;
297 ScRange aReducedBlock
= aBlock
;
298 if ( nFormat
== SOT_FORMATSTR_ID_HTML
&& (aBlock
.aEnd
.Col() == MAXCOL
|| aBlock
.aEnd
.Row() == MAXROW
) && aBlock
.aStart
.Tab() == aBlock
.aEnd
.Tab() )
300 bool bShrunk
= false;
301 //shrink the area to allow pasting to external applications
302 SCCOL aStartCol
= aReducedBlock
.aStart
.Col();
303 SCROW aStartRow
= aReducedBlock
.aStart
.Row();
304 SCCOL aEndCol
= aReducedBlock
.aEnd
.Col();
305 SCROW aEndRow
= aReducedBlock
.aEnd
.Row();
306 pDoc
->ShrinkToUsedDataArea( bShrunk
, aReducedBlock
.aStart
.Tab(), aStartCol
, aStartRow
, aEndCol
, aEndRow
, false);
307 aReducedBlock
= ScRange(aStartCol
, aStartRow
, aReducedBlock
.aStart
.Tab(), aEndCol
, aEndRow
, aReducedBlock
.aEnd
.Tab());
310 ScImportExport
aObj( pDoc
, aReducedBlock
);
311 ScExportTextOptions
aTextOptions(ScExportTextOptions::None
, 0, true);
314 // For a DDE link, convert line breaks and separators to space.
315 aTextOptions
.meNewlineConversion
= ScExportTextOptions::ToSpace
;
316 aTextOptions
.mcSeparatorConvertTo
= ' ';
317 aTextOptions
.mbAddQuotes
= false;
319 aObj
.SetExportTextOptions(aTextOptions
);
320 aObj
.SetFormulas( pDoc
->GetViewOptions().GetOption( VOPT_FORMULAS
) );
321 aObj
.SetIncludeFiltered( bIncludeFiltered
);
323 // DataType depends on format type:
325 if ( rFlavor
.DataType
.equals( ::getCppuType( (const OUString
*) 0 ) ) )
328 if ( aObj
.ExportString( aString
, nFormat
) )
329 bOK
= SetString( aString
, rFlavor
);
331 else if ( rFlavor
.DataType
.equals( ::getCppuType( (const uno::Sequence
< sal_Int8
>*) 0 ) ) )
333 // SetObject converts a stream into a Int8-Sequence
334 bOK
= SetObject( &aObj
, SCTRANS_TYPE_IMPEX
, rFlavor
);
338 OSL_FAIL("unknown DataType");
341 else if ( nFormat
== SOT_FORMAT_BITMAP
)
343 Rectangle aMMRect
= pDoc
->GetMMRect( aBlock
.aStart
.Col(), aBlock
.aStart
.Row(),
344 aBlock
.aEnd
.Col(), aBlock
.aEnd
.Row(),
345 aBlock
.aStart
.Tab() );
346 VirtualDevice aVirtDev
;
347 aVirtDev
.SetOutputSizePixel( aVirtDev
.LogicToPixel( aMMRect
.GetSize(), MAP_100TH_MM
) );
349 PaintToDev( &aVirtDev
, pDoc
, 1.0, aBlock
, false );
351 aVirtDev
.SetMapMode( MapMode( MAP_PIXEL
) );
352 Bitmap aBmp
= aVirtDev
.GetBitmap( Point(), aVirtDev
.GetOutputSize() );
353 bOK
= SetBitmapEx( aBmp
, rFlavor
);
355 else if ( nFormat
== SOT_FORMAT_GDIMETAFILE
)
357 // #i123405# Do not limit visual size calculation for metafile creation.
358 // It seems unlikely that removing the limitation causes problems since
359 // metafile creation means that no real pixel device in the needed size is
363 SfxObjectShell
* pEmbObj
= aDocShellRef
;
365 // like SvEmbeddedTransfer::GetData:
368 MapMode
aMapMode( pEmbObj
->GetMapUnit() );
369 Rectangle
aVisArea( pEmbObj
->GetVisArea( ASPECT_CONTENT
) );
371 aVDev
.EnableOutput( false );
372 aVDev
.SetMapMode( aMapMode
);
373 aMtf
.SetPrefSize( aVisArea
.GetSize() );
374 aMtf
.SetPrefMapMode( aMapMode
);
375 aMtf
.Record( &aVDev
);
377 pEmbObj
->DoDraw( &aVDev
, Point(), aVisArea
.GetSize(), JobSetup(), ASPECT_CONTENT
);
382 bOK
= SetGDIMetaFile( aMtf
, rFlavor
);
384 else if ( nFormat
== SOT_FORMATSTR_ID_EMBED_SOURCE
)
386 //TODO/LATER: differentiate between formats?!
387 // #i123405# Do limit visual size calculation to PageSize
388 InitDocShell(true); // set aDocShellRef
390 SfxObjectShell
* pEmbObj
= aDocShellRef
;
391 bOK
= SetObject( pEmbObj
, SCTRANS_TYPE_EMBOBJ
, rFlavor
);
397 sal_Bool
ScTransferObj::WriteObject( SotStorageStreamRef
& rxOStm
, void* pUserObject
, sal_uInt32 nUserObjectId
,
398 const datatransfer::DataFlavor
& rFlavor
)
400 // called from SetObject, put data into stream
403 switch (nUserObjectId
)
405 case SCTRANS_TYPE_IMPEX
:
407 ScImportExport
* pImpEx
= (ScImportExport
*)pUserObject
;
409 sal_uInt32 nFormat
= SotExchange::GetFormat( rFlavor
);
410 // mba: no BaseURL for data exchange
411 if ( pImpEx
->ExportStream( *rxOStm
, OUString(), nFormat
) )
412 bRet
= ( rxOStm
->GetError() == ERRCODE_NONE
);
416 case SCTRANS_TYPE_EDIT_RTF
:
417 case SCTRANS_TYPE_EDIT_BIN
:
419 ScTabEditEngine
* pEngine
= (ScTabEditEngine
*)pUserObject
;
420 if ( nUserObjectId
== SCTRANS_TYPE_EDIT_RTF
)
422 pEngine
->Write( *rxOStm
, EE_FORMAT_RTF
);
423 bRet
= ( rxOStm
->GetError() == ERRCODE_NONE
);
427 // can't use Write for EditEngine format because that would
428 // write old format without support for unicode characters.
429 // Get the data from the EditEngine's transferable instead.
431 sal_Int32 nParCnt
= pEngine
->GetParagraphCount();
434 ESelection
aSel( 0, 0, nParCnt
-1, pEngine
->GetTextLen(nParCnt
-1) );
436 uno::Reference
<datatransfer::XTransferable
> xEditTrans
= pEngine
->CreateTransferable( aSel
);
437 TransferableDataHelper
aEditHelper( xEditTrans
);
439 bRet
= aEditHelper
.GetSotStorageStream( rFlavor
, rxOStm
);
444 case SCTRANS_TYPE_EMBOBJ
:
447 SfxObjectShell
* pEmbObj
= (SfxObjectShell
*) pUserObject
;
448 ::utl::TempFile aTempFile
;
449 aTempFile
.EnableKillingFile();
450 uno::Reference
< embed::XStorage
> xWorkStore
=
451 ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile
.GetURL(), embed::ElementModes::READWRITE
);
453 // write document storage
454 pEmbObj
->SetupStorage( xWorkStore
, SOFFICE_FILEFORMAT_CURRENT
, false, false );
456 // mba: no relative ULRs for clipboard!
457 SfxMedium
aMedium( xWorkStore
, OUString() );
458 bRet
= pEmbObj
->DoSaveObjectAs( aMedium
, false );
459 pEmbObj
->DoSaveCompleted();
461 uno::Reference
< embed::XTransactedObject
> xTransact( xWorkStore
, uno::UNO_QUERY
);
462 if ( xTransact
.is() )
465 SvStream
* pSrcStm
= ::utl::UcbStreamHelper::CreateStream( aTempFile
.GetURL(), STREAM_READ
);
468 rxOStm
->SetBufferSize( 0xff00 );
475 xWorkStore
->dispose();
476 xWorkStore
= uno::Reference
< embed::XStorage
>();
482 OSL_FAIL("unknown object id");
487 void ScTransferObj::ObjectReleased()
489 ScModule
* pScMod
= SC_MOD();
490 if ( pScMod
->GetClipData().pCellClipboard
== this )
491 pScMod
->SetClipObject( NULL
, NULL
);
493 TransferableHelper::ObjectReleased();
496 void ScTransferObj::DragFinished( sal_Int8 nDropAction
)
498 if ( nDropAction
== DND_ACTION_MOVE
&& !bDragWasInternal
&& !(nDragSourceFlags
& SC_DROP_NAVIGATOR
) )
500 // move: delete source data
501 ScDocShell
* pSourceSh
= GetSourceDocShell();
504 ScMarkData aMarkData
= GetSourceMarkData();
505 // external drag&drop doesn't copy objects, so they also aren't deleted:
506 // bApi=TRUE, don't show error messages from drag&drop
507 pSourceSh
->GetDocFunc().DeleteContents( aMarkData
, IDF_ALL
& ~IDF_OBJECTS
, true, true );
511 ScModule
* pScMod
= SC_MOD();
512 if ( pScMod
->GetDragData().pCellTransfer
== this )
513 pScMod
->ResetDragObject();
515 xDragSourceRanges
= NULL
; // don't keep source after dropping
517 TransferableHelper::DragFinished( nDropAction
);
520 void ScTransferObj::SetDragHandlePos( SCCOL nX
, SCROW nY
)
526 void ScTransferObj::SetVisibleTab( SCTAB nNew
)
531 void ScTransferObj::SetDrawPersist( const SfxObjectShellRef
& rRef
)
533 aDrawPersistRef
= rRef
;
536 void ScTransferObj::SetDragSource( ScDocShell
* pSourceShell
, const ScMarkData
& rMark
)
539 rMark
.FillRangeListWithMarks( &aRanges
, false );
540 xDragSourceRanges
= new ScCellRangesObj( pSourceShell
, aRanges
);
543 void ScTransferObj::SetDragSourceFlags( sal_uInt16 nFlags
)
545 nDragSourceFlags
= nFlags
;
548 void ScTransferObj::SetDragWasInternal()
550 bDragWasInternal
= true;
553 void ScTransferObj::SetUseInApi( bool bSet
)
558 ScDocument
* ScTransferObj::GetSourceDocument()
560 ScDocShell
* pSourceDocSh
= GetSourceDocShell();
562 return pSourceDocSh
->GetDocument();
566 ScDocShell
* ScTransferObj::GetSourceDocShell()
568 ScCellRangesBase
* pRangesObj
= ScCellRangesBase::getImplementation( xDragSourceRanges
);
570 return pRangesObj
->GetDocShell();
572 return NULL
; // none set
575 ScMarkData
ScTransferObj::GetSourceMarkData()
577 ScMarkData aMarkData
;
578 ScCellRangesBase
* pRangesObj
= ScCellRangesBase::getImplementation( xDragSourceRanges
);
581 const ScRangeList
& rRanges
= pRangesObj
->GetRangeList();
582 aMarkData
.MarkFromRangeList( rRanges
, false );
588 // initialize aDocShellRef with a live document from the ClipDoc
590 // #i123405# added parameter to allow size calculation without limitation
591 // to PageSize, e.g. used for Metafile creation for clipboard.
593 void ScTransferObj::InitDocShell(bool bLimitToPageSize
)
595 if ( !aDocShellRef
.Is() )
597 ScDocShell
* pDocSh
= new ScDocShell
;
598 aDocShellRef
= pDocSh
; // ref must be there before InitNew
600 pDocSh
->DoInitNew(NULL
);
602 ScDocument
* pDestDoc
= pDocSh
->GetDocument();
603 ScMarkData aDestMark
;
604 aDestMark
.SelectTable( 0, true );
606 pDestDoc
->SetDocOptions( pDoc
->GetDocOptions() ); // #i42666#
609 pDoc
->GetName( aBlock
.aStart
.Tab(), aTabName
);
610 pDestDoc
->RenameTab( 0, aTabName
, false ); // no UpdateRef (empty)
612 pDestDoc
->CopyStdStylesFrom( pDoc
);
614 SCCOL nStartX
= aBlock
.aStart
.Col();
615 SCROW nStartY
= aBlock
.aStart
.Row();
616 SCCOL nEndX
= aBlock
.aEnd
.Col();
617 SCROW nEndY
= aBlock
.aEnd
.Row();
620 // (must be copied before CopyFromClip, for drawing objects)
623 SCTAB nSrcTab
= aBlock
.aStart
.Tab();
624 pDestDoc
->SetLayoutRTL(0, pDoc
->IsLayoutRTL(nSrcTab
));
625 for (nCol
=nStartX
; nCol
<=nEndX
; nCol
++)
626 if ( pDoc
->ColHidden(nCol
, nSrcTab
) )
627 pDestDoc
->ShowCol( nCol
, 0, false );
629 pDestDoc
->SetColWidth( nCol
, 0, pDoc
->GetColWidth( nCol
, nSrcTab
) );
631 for (SCROW nRow
= nStartY
; nRow
<= nEndY
; ++nRow
)
633 if ( pDoc
->RowHidden(nRow
, nSrcTab
) )
634 pDestDoc
->ShowRow( nRow
, 0, false );
637 pDestDoc
->SetRowHeight( nRow
, 0, pDoc
->GetOriginalHeight( nRow
, nSrcTab
) );
639 // if height was set manually, that flag has to be copied, too
640 bool bManual
= pDoc
->IsManualRowHeight(nRow
, nSrcTab
);
641 pDestDoc
->SetManualHeight(nRow
, nRow
, 0, bManual
);
645 if ( pDoc
->GetDrawLayer() )
646 pDocSh
->MakeDrawLayer();
648 // cell range is copied to the original position, but on the first sheet
649 // -> bCutMode must be set
650 // pDoc is always a Clipboard-document
652 ScRange
aDestRange( nStartX
,nStartY
,0, nEndX
,nEndY
,0 );
653 bool bWasCut
= pDoc
->IsCutMode();
655 pDoc
->SetClipArea( aDestRange
, true ); // Cut
656 pDestDoc
->CopyFromClip( aDestRange
, aDestMark
, IDF_ALL
, NULL
, pDoc
, false );
657 pDoc
->SetClipArea( aDestRange
, bWasCut
);
659 StripRefs( pDoc
, nStartX
,nStartY
, nEndX
,nEndY
, pDestDoc
, 0,0 );
661 ScRange aMergeRange
= aDestRange
;
662 pDestDoc
->ExtendMerge( aMergeRange
, true );
664 pDoc
->CopyDdeLinks( pDestDoc
); // copy values of DDE Links
666 // page format (grid etc) and page size (maximum size for ole object)
668 Size aPaperSize
= SvxPaperInfo::GetPaperSize( PAPER_A4
); // Twips
669 ScStyleSheetPool
* pStylePool
= pDoc
->GetStyleSheetPool();
670 OUString aStyleName
= pDoc
->GetPageStyle( aBlock
.aStart
.Tab() );
671 SfxStyleSheetBase
* pStyleSheet
= pStylePool
->Find( aStyleName
, SFX_STYLE_FAMILY_PAGE
);
674 const SfxItemSet
& rSourceSet
= pStyleSheet
->GetItemSet();
675 aPaperSize
= ((const SvxSizeItem
&) rSourceSet
.Get(ATTR_PAGE_SIZE
)).GetSize();
677 // CopyStyleFrom kopiert SetItems mit richtigem Pool
678 ScStyleSheetPool
* pDestPool
= pDestDoc
->GetStyleSheetPool();
679 pDestPool
->CopyStyleFrom( pStylePool
, aStyleName
, SFX_STYLE_FAMILY_PAGE
);
682 ScViewData
aViewData( pDocSh
, NULL
);
683 aViewData
.SetScreen( nStartX
,nStartY
, nEndX
,nEndY
);
684 aViewData
.SetCurX( nStartX
);
685 aViewData
.SetCurY( nStartY
);
687 pDestDoc
->SetViewOptions( pDoc
->GetViewOptions() );
690 //! get while copying sizes
695 for (nCol
=0; nCol
<nStartX
; nCol
++)
696 nPosX
+= pDestDoc
->GetColWidth( nCol
, 0 );
697 nPosY
+= pDestDoc
->GetRowHeight( 0, nStartY
-1, 0 );
698 nPosX
= (long) ( nPosX
* HMM_PER_TWIPS
);
699 nPosY
= (long) ( nPosY
* HMM_PER_TWIPS
);
702 aPaperSize
.Width() *= 2; // limit OLE object to double of page size
703 aPaperSize
.Height() *= 2;
707 for (nCol
=nStartX
; nCol
<=nEndX
; nCol
++)
709 long nAdd
= pDestDoc
->GetColWidth( nCol
, 0 );
710 if ( bLimitToPageSize
&& nSizeX
+nAdd
> aPaperSize
.Width() && nSizeX
) // above limit?
714 for (SCROW nRow
=nStartY
; nRow
<=nEndY
; nRow
++)
716 long nAdd
= pDestDoc
->GetRowHeight( nRow
, 0 );
717 if ( bLimitToPageSize
&& nSizeY
+nAdd
> aPaperSize
.Height() && nSizeY
) // above limit?
721 nSizeX
= (long) ( nSizeX
* HMM_PER_TWIPS
);
722 nSizeY
= (long) ( nSizeY
* HMM_PER_TWIPS
);
724 // pDocSh->SetVisAreaSize( Size(nSizeX,nSizeY) );
726 Rectangle
aNewArea( Point(nPosX
,nPosY
), Size(nSizeX
,nSizeY
) );
727 //TODO/LATER: why twice?!
728 //pDocSh->SvInPlaceObject::SetVisArea( aNewArea );
729 pDocSh
->SetVisArea( aNewArea
);
731 pDocSh
->UpdateOle(&aViewData
, true);
733 //! SetDocumentModified?
734 if ( pDestDoc
->IsChartListenerCollectionNeedsUpdate() )
735 pDestDoc
->UpdateChartListenerCollection();
739 SfxObjectShell
* ScTransferObj::SetDrawClipDoc( sal_Bool bAnyOle
)
741 // update ScGlobal::pDrawClipDocShellRef
743 delete ScGlobal::pDrawClipDocShellRef
;
746 ScGlobal::pDrawClipDocShellRef
=
747 new ScDocShellRef(new ScDocShell(SFX_CREATE_MODE_INTERNAL
)); // there must be a ref
748 (*ScGlobal::pDrawClipDocShellRef
)->DoInitNew(NULL
);
749 return *ScGlobal::pDrawClipDocShellRef
;
753 ScGlobal::pDrawClipDocShellRef
= NULL
;
758 void ScTransferObj::StripRefs( ScDocument
* pDoc
,
759 SCCOL nStartX
, SCROW nStartY
, SCCOL nEndX
, SCROW nEndY
,
760 ScDocument
* pDestDoc
, SCCOL nSubX
, SCROW nSubY
)
765 OSL_ENSURE(nSubX
==0&&nSubY
==0, "can't move within the document");
768 // In a clipboard doc the data don't have to be on the first sheet
771 while (nSrcTab
<pDoc
->GetTableCount() && !pDoc
->HasTable(nSrcTab
))
774 while (nDestTab
<pDestDoc
->GetTableCount() && !pDestDoc
->HasTable(nDestTab
))
777 if (!pDoc
->HasTable(nSrcTab
) || !pDestDoc
->HasTable(nDestTab
))
779 OSL_FAIL("Sheet not found in ScTransferObj::StripRefs");
785 ScCellIterator
aIter( pDoc
, ScRange(nStartX
, nStartY
, nSrcTab
, nEndX
, nEndY
, nSrcTab
) );
786 for (bool bHas
= aIter
.first(); bHas
; bHas
= aIter
.next())
788 if (aIter
.getType() != CELLTYPE_FORMULA
)
791 ScFormulaCell
* pFCell
= aIter
.getFormulaCell();
793 ScDetectiveRefIter
aRefIter( pFCell
);
794 while ( !bOut
&& aRefIter
.GetNextRef( aRef
) )
796 if ( aRef
.aStart
.Tab() != nSrcTab
|| aRef
.aEnd
.Tab() != nSrcTab
||
797 aRef
.aStart
.Col() < nStartX
|| aRef
.aEnd
.Col() > nEndX
||
798 aRef
.aStart
.Row() < nStartY
|| aRef
.aEnd
.Row() > nEndY
)
803 SCCOL nCol
= aIter
.GetPos().Col() - nSubX
;
804 SCROW nRow
= aIter
.GetPos().Row() - nSubY
;
806 sal_uInt16 nErrCode
= pFCell
->GetErrCode();
807 ScAddress
aPos(nCol
, nRow
, nDestTab
);
810 if ( ((const SvxHorJustifyItem
*) pDestDoc
->GetAttr(
811 nCol
,nRow
,nDestTab
, ATTR_HOR_JUSTIFY
))->GetValue() ==
812 SVX_HOR_JUSTIFY_STANDARD
)
813 pDestDoc
->ApplyAttr( nCol
,nRow
,nDestTab
,
814 SvxHorJustifyItem(SVX_HOR_JUSTIFY_RIGHT
, ATTR_HOR_JUSTIFY
) );
816 ScSetStringParam aParam
;
817 aParam
.setTextInput();
818 pDestDoc
->SetString(aPos
, ScGlobal::GetErrorString(nErrCode
), &aParam
);
820 else if (pFCell
->IsValue())
822 pDestDoc
->SetValue(aPos
, pFCell
->GetValue());
826 OUString aStr
= pFCell
->GetString().getString();
827 if ( pFCell
->IsMultilineResult() )
829 ScFieldEditEngine
& rEngine
= pDestDoc
->GetEditEngine();
830 rEngine
.SetText(aStr
);
831 pDestDoc
->SetEditText(ScAddress(nCol
,nRow
,nDestTab
), rEngine
.CreateTextObject());
835 ScSetStringParam aParam
;
836 aParam
.setTextInput();
837 pDestDoc
->SetString(aPos
, aStr
, &aParam
);
846 class theScTransferUnoTunnelId
: public rtl::Static
< UnoTunnelIdInit
, theScTransferUnoTunnelId
> {};
849 const com::sun::star::uno::Sequence
< sal_Int8
>& ScTransferObj::getUnoTunnelId()
851 return theScTransferUnoTunnelId::get().getSeq();
854 sal_Int64 SAL_CALL
ScTransferObj::getSomething( const com::sun::star::uno::Sequence
< sal_Int8
>& rId
) throw( com::sun::star::uno::RuntimeException
)
857 if( ( rId
.getLength() == 16 ) &&
858 ( 0 == memcmp( getUnoTunnelId().getConstArray(), rId
.getConstArray(), 16 ) ) )
860 nRet
= reinterpret_cast< sal_Int64
>( this );
863 nRet
= TransferableHelper::getSomething(rId
);
868 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */