Update ooo320-m1
[ooovba.git] / sc / source / ui / app / transobj.cxx
blob87f888c9055ff247f4f012a4330de280a03d8de6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: transobj.cxx,v $
10 * $Revision: 1.34 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 // INCLUDE ---------------------------------------------------------------
38 #include "scitems.hxx"
39 #include <svx/eeitem.hxx>
42 #include <com/sun/star/uno/Sequence.hxx>
43 #include <com/sun/star/embed/XTransactedObject.hpp>
45 #include <unotools/tempfile.hxx>
46 #include <unotools/ucbstreamhelper.hxx>
47 #include <comphelper/storagehelper.hxx>
48 #include <sot/storage.hxx>
49 #include <vcl/svapp.hxx>
50 #include <vcl/virdev.hxx>
51 #include <vos/mutex.hxx>
52 #include <sfx2/app.hxx>
53 #include <sfx2/docfile.hxx>
55 #include "transobj.hxx"
56 #include "document.hxx"
57 #include "viewopti.hxx"
58 #include "editutil.hxx"
59 #include "impex.hxx"
60 #include "cell.hxx"
61 #include "printfun.hxx"
62 #include "docfunc.hxx"
63 #include "scmod.hxx"
65 // for InitDocShell
66 #include <svx/paperinf.hxx>
67 #include <svx/sizeitem.hxx>
68 #include <svx/algitem.hxx>
69 #include <svtools/intitem.hxx>
70 #include <svtools/zforlist.hxx>
71 #include "docsh.hxx"
72 #include "markdata.hxx"
73 #include "stlpool.hxx"
74 #include "viewdata.hxx"
75 #include "dociter.hxx"
76 #include "cellsuno.hxx"
78 using namespace com::sun::star;
80 // -----------------------------------------------------------------------
82 #define SCTRANS_TYPE_IMPEX 1
83 #define SCTRANS_TYPE_EDIT_RTF 2
84 #define SCTRANS_TYPE_EDIT_BIN 3
85 #define SCTRANS_TYPE_EMBOBJ 4
87 // -----------------------------------------------------------------------
89 // static
90 void ScTransferObj::GetAreaSize( ScDocument* pDoc, SCTAB nTab1, SCTAB nTab2, SCROW& nRow, SCCOL& nCol )
92 SCCOL nMaxCol = 0;
93 SCROW nMaxRow = 0;
94 for( SCTAB nTab = nTab1; nTab <= nTab2; nTab++ )
96 SCCOL nLastCol = 0;
97 SCROW nLastRow = 0;
98 // GetPrintArea instead of GetCellArea - include drawing objects
99 if( pDoc->GetPrintArea( nTab, nLastCol, nLastRow ) )
101 if( nLastCol > nMaxCol )
102 nMaxCol = nLastCol;
103 if( nLastRow > nMaxRow )
104 nMaxRow = nLastRow;
107 nRow = nMaxRow;
108 nCol = nMaxCol;
111 // static
112 void ScTransferObj::PaintToDev( OutputDevice* pDev, ScDocument* pDoc, double nPrintFactor,
113 const ScRange& rBlock, BOOL bMetaFile )
115 if (!pDoc)
116 return;
118 Point aPoint;
119 Rectangle aBound( aPoint, pDev->GetOutputSize() ); //! use size from clip area?
121 ScViewData aViewData(NULL,NULL);
122 aViewData.InitData( pDoc );
124 aViewData.SetTabNo( rBlock.aEnd.Tab() );
125 aViewData.SetScreen( rBlock.aStart.Col(), rBlock.aStart.Row(),
126 rBlock.aEnd.Col(), rBlock.aEnd.Row() );
128 ScPrintFunc::DrawToDev( pDoc, pDev, nPrintFactor, aBound, &aViewData, bMetaFile );
131 // -----------------------------------------------------------------------
133 ScTransferObj::ScTransferObj( ScDocument* pClipDoc, const TransferableObjectDescriptor& rDesc ) :
134 pDoc( pClipDoc ),
135 aObjDesc( rDesc ),
136 nDragHandleX( 0 ),
137 nDragHandleY( 0 ),
138 nDragSourceFlags( 0 ),
139 bDragWasInternal( FALSE ),
140 bUsedForLink( FALSE )
142 DBG_ASSERT(pDoc->IsClipboard(), "wrong document");
145 // get aBlock from clipboard doc
148 SCCOL nCol1;
149 SCROW nRow1;
150 SCCOL nCol2;
151 SCROW nRow2;
152 pDoc->GetClipStart( nCol1, nRow1 );
153 pDoc->GetClipArea( nCol2, nRow2, TRUE ); // real source area - include filtered rows
154 nCol2 = sal::static_int_cast<SCCOL>( nCol2 + nCol1 );
155 nRow2 = sal::static_int_cast<SCROW>( nRow2 + nRow1 );
157 SCCOL nDummy;
158 pDoc->GetClipArea( nDummy, nNonFiltered, FALSE );
159 bHasFiltered = (nNonFiltered < (nRow2 - nRow1));
160 ++nNonFiltered; // to get count instead of diff
162 SCTAB nTab1=0;
163 SCTAB nTab2=0;
164 BOOL bFirst = TRUE;
165 for (SCTAB i=0; i<=MAXTAB; i++)
166 if (pDoc->HasTable(i))
168 if (bFirst)
169 nTab1 = i;
170 nTab2 = i;
171 bFirst = FALSE;
173 DBG_ASSERT(!bFirst, "no sheet selected");
175 // only limit to used cells if whole sheet was marked
176 // (so empty cell areas can be copied)
177 if ( nCol2>=MAXCOL && nRow2>=MAXROW )
179 SCROW nMaxRow;
180 SCCOL nMaxCol;
181 GetAreaSize( pDoc, nTab1, nTab2, nMaxRow, nMaxCol );
182 if( nMaxRow < nRow2 )
183 nRow2 = nMaxRow;
184 if( nMaxCol < nCol2 )
185 nCol2 = nMaxCol;
188 aBlock = ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
189 nVisibleTab = nTab1; // valid table as default
191 Rectangle aMMRect = pDoc->GetMMRect( nCol1,nRow1, nCol2,nRow2, nTab1 );
192 aObjDesc.maSize = aMMRect.GetSize();
193 PrepareOLE( aObjDesc );
196 ScTransferObj::~ScTransferObj()
198 Application::GetSolarMutex().acquire();
200 ScModule* pScMod = SC_MOD();
201 if ( pScMod->GetClipData().pCellClipboard == this )
203 DBG_ERROR("ScTransferObj wasn't released");
204 pScMod->SetClipObject( NULL, NULL );
206 if ( pScMod->GetDragData().pCellTransfer == this )
208 DBG_ERROR("ScTransferObj wasn't released");
209 pScMod->ResetDragObject();
212 delete pDoc; // ScTransferObj is owner of clipboard document
214 aDocShellRef.Clear(); // before releasing the mutex
216 aDrawPersistRef.Clear(); // after the model
218 Application::GetSolarMutex().release();
221 // static
222 ScTransferObj* ScTransferObj::GetOwnClipboard( Window* pUIWin )
224 ScTransferObj* pObj = SC_MOD()->GetClipData().pCellClipboard;
225 if ( pObj && pUIWin )
227 // check formats to see if pObj is really in the system clipboard
229 // pUIWin is NULL when called from core (IsClipboardSource),
230 // in that case don't access the system clipboard, because the call
231 // may be from other clipboard operations (like flushing, #86059#)
233 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pUIWin ) );
234 if ( !aDataHelper.HasFormat( SOT_FORMATSTR_ID_DIF ) )
236 // DBG_ERROR("ScTransferObj wasn't released");
237 pObj = NULL;
240 return pObj;
243 void ScTransferObj::AddSupportedFormats()
245 AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
246 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
247 AddFormat( SOT_FORMAT_GDIMETAFILE );
248 AddFormat( SOT_FORMAT_BITMAP );
250 // ScImportExport formats
251 AddFormat( SOT_FORMATSTR_ID_HTML );
252 AddFormat( SOT_FORMATSTR_ID_SYLK );
253 AddFormat( SOT_FORMATSTR_ID_LINK );
254 AddFormat( SOT_FORMATSTR_ID_DIF );
255 AddFormat( SOT_FORMAT_STRING );
257 AddFormat( SOT_FORMAT_RTF );
258 if ( aBlock.aStart == aBlock.aEnd )
259 AddFormat( SOT_FORMATSTR_ID_EDITENGINE );
262 sal_Bool ScTransferObj::GetData( const datatransfer::DataFlavor& rFlavor )
264 sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor );
265 sal_Bool bOK = sal_False;
267 if( HasFormat( nFormat ) )
269 if ( nFormat == SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR || nFormat == SOT_FORMATSTR_ID_OBJECTDESCRIPTOR )
271 bOK = SetTransferableObjectDescriptor( aObjDesc, rFlavor );
273 else if ( ( nFormat == SOT_FORMAT_RTF || nFormat == SOT_FORMATSTR_ID_EDITENGINE ) &&
274 aBlock.aStart == aBlock.aEnd )
276 // RTF from a single cell is handled by EditEngine
278 SCCOL nCol = aBlock.aStart.Col();
279 SCROW nRow = aBlock.aStart.Row();
280 SCTAB nTab = aBlock.aStart.Tab();
282 const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
283 ScTabEditEngine aEngine( *pPattern, pDoc->GetEditPool() );
284 ScBaseCell* pCell = NULL;
285 pDoc->GetCell( nCol, nRow, nTab, pCell );
286 if (pCell)
288 if (pCell->GetCellType() == CELLTYPE_EDIT)
290 const EditTextObject* pObj;
291 ((ScEditCell*)pCell)->GetData(pObj);
292 aEngine.SetText( *pObj );
294 else
296 String aText;
297 pDoc->GetString( nCol, nRow, nTab, aText );
298 aEngine.SetText(aText);
302 bOK = SetObject( &aEngine,
303 (nFormat == FORMAT_RTF) ? SCTRANS_TYPE_EDIT_RTF : SCTRANS_TYPE_EDIT_BIN,
304 rFlavor );
306 else if ( ScImportExport::IsFormatSupported( nFormat ) || nFormat == SOT_FORMAT_RTF )
308 // if this transfer object was used to create a DDE link, filtered rows
309 // have to be included for subsequent calls (to be consistent with link data)
310 if ( nFormat == SOT_FORMATSTR_ID_LINK )
311 bUsedForLink = TRUE;
313 BOOL bIncludeFiltered = pDoc->IsCutMode() || bUsedForLink;
315 ScImportExport aObj( pDoc, aBlock );
316 if ( bUsedForLink )
317 aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, ' ', false ) );
318 aObj.SetFormulas( pDoc->GetViewOptions().GetOption( VOPT_FORMULAS ) );
319 aObj.SetIncludeFiltered( bIncludeFiltered );
321 // DataType depends on format type:
323 if ( rFlavor.DataType.equals( ::getCppuType( (const ::rtl::OUString*) 0 ) ) )
325 rtl::OUString aString;
326 if ( aObj.ExportString( aString, nFormat ) )
327 bOK = SetString( aString, rFlavor );
329 else if ( rFlavor.DataType.equals( ::getCppuType( (const uno::Sequence< sal_Int8 >*) 0 ) ) )
331 // SetObject converts a stream into a Int8-Sequence
332 bOK = SetObject( &aObj, SCTRANS_TYPE_IMPEX, rFlavor );
334 else
336 DBG_ERROR("unknown DataType");
339 else if ( nFormat == SOT_FORMAT_BITMAP )
341 Rectangle aMMRect = pDoc->GetMMRect( aBlock.aStart.Col(), aBlock.aStart.Row(),
342 aBlock.aEnd.Col(), aBlock.aEnd.Row(),
343 aBlock.aStart.Tab() );
344 VirtualDevice aVirtDev;
345 aVirtDev.SetOutputSizePixel( aVirtDev.LogicToPixel( aMMRect.GetSize(), MAP_100TH_MM ) );
347 PaintToDev( &aVirtDev, pDoc, 1.0, aBlock, FALSE );
349 aVirtDev.SetMapMode( MapMode( MAP_PIXEL ) );
350 Bitmap aBmp = aVirtDev.GetBitmap( Point(), aVirtDev.GetOutputSize() );
351 bOK = SetBitmap( aBmp, rFlavor );
353 else if ( nFormat == SOT_FORMAT_GDIMETAFILE )
355 InitDocShell();
356 SfxObjectShell* pEmbObj = aDocShellRef;
358 // like SvEmbeddedTransfer::GetData:
360 GDIMetaFile aMtf;
361 VirtualDevice aVDev;
362 MapMode aMapMode( pEmbObj->GetMapUnit() );
363 Rectangle aVisArea( pEmbObj->GetVisArea( ASPECT_CONTENT ) );
365 aVDev.EnableOutput( FALSE );
366 aVDev.SetMapMode( aMapMode );
367 aMtf.SetPrefSize( aVisArea.GetSize() );
368 aMtf.SetPrefMapMode( aMapMode );
369 aMtf.Record( &aVDev );
371 pEmbObj->DoDraw( &aVDev, Point(), aVisArea.GetSize(), JobSetup(), ASPECT_CONTENT );
373 aMtf.Stop();
374 aMtf.WindStart();
376 bOK = SetGDIMetaFile( aMtf, rFlavor );
378 else if ( nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE )
380 //TODO/LATER: differentiate between formats?!
381 InitDocShell(); // set aDocShellRef
383 SfxObjectShell* pEmbObj = aDocShellRef;
384 bOK = SetObject( pEmbObj, SCTRANS_TYPE_EMBOBJ, rFlavor );
387 return bOK;
390 sal_Bool ScTransferObj::WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId,
391 const datatransfer::DataFlavor& rFlavor )
393 // called from SetObject, put data into stream
395 sal_Bool bRet = sal_False;
396 switch (nUserObjectId)
398 case SCTRANS_TYPE_IMPEX:
400 ScImportExport* pImpEx = (ScImportExport*)pUserObject;
402 sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor );
403 // mba: no BaseURL for data exchange
404 if ( pImpEx->ExportStream( *rxOStm, String(), nFormat ) )
405 bRet = ( rxOStm->GetError() == ERRCODE_NONE );
407 break;
409 case SCTRANS_TYPE_EDIT_RTF:
410 case SCTRANS_TYPE_EDIT_BIN:
412 ScTabEditEngine* pEngine = (ScTabEditEngine*)pUserObject;
413 if ( nUserObjectId == SCTRANS_TYPE_EDIT_RTF )
415 pEngine->Write( *rxOStm, EE_FORMAT_RTF );
416 bRet = ( rxOStm->GetError() == ERRCODE_NONE );
418 else
420 // #107722# can't use Write for EditEngine format because that would
421 // write old format without support for unicode characters.
422 // Get the data from the EditEngine's transferable instead.
424 USHORT nParCnt = pEngine->GetParagraphCount();
425 if ( nParCnt == 0 )
426 nParCnt = 1;
427 ESelection aSel( 0, 0, nParCnt-1, pEngine->GetTextLen(nParCnt-1) );
429 uno::Reference<datatransfer::XTransferable> xEditTrans = pEngine->CreateTransferable( aSel );
430 TransferableDataHelper aEditHelper( xEditTrans );
432 bRet = aEditHelper.GetSotStorageStream( rFlavor, rxOStm );
435 break;
437 case SCTRANS_TYPE_EMBOBJ:
439 // TODO/MBA: testing
440 SfxObjectShell* pEmbObj = (SfxObjectShell*) pUserObject;
441 ::utl::TempFile aTempFile;
442 aTempFile.EnableKillingFile();
443 uno::Reference< embed::XStorage > xWorkStore =
444 ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
446 // write document storage
447 pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, sal_False );
449 // mba: no relative ULRs for clipboard!
450 SfxMedium aMedium( xWorkStore, String() );
451 bRet = pEmbObj->DoSaveObjectAs( aMedium, FALSE );
452 pEmbObj->DoSaveCompleted();
454 uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY );
455 if ( xTransact.is() )
456 xTransact->commit();
458 SvStream* pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), STREAM_READ );
459 if( pSrcStm )
461 rxOStm->SetBufferSize( 0xff00 );
462 *rxOStm << *pSrcStm;
463 delete pSrcStm;
466 bRet = TRUE;
468 xWorkStore->dispose();
469 xWorkStore = uno::Reference < embed::XStorage >();
470 rxOStm->Commit();
472 break;
474 default:
475 DBG_ERROR("unknown object id");
477 return bRet;
480 void ScTransferObj::ObjectReleased()
482 ScModule* pScMod = SC_MOD();
483 if ( pScMod->GetClipData().pCellClipboard == this )
484 pScMod->SetClipObject( NULL, NULL );
486 TransferableHelper::ObjectReleased();
489 void ScTransferObj::DragFinished( sal_Int8 nDropAction )
491 if ( nDropAction == DND_ACTION_MOVE && !bDragWasInternal && !(nDragSourceFlags & SC_DROP_NAVIGATOR) )
493 // move: delete source data
494 ScDocShell* pSourceSh = GetSourceDocShell();
495 if (pSourceSh)
497 ScMarkData aMarkData = GetSourceMarkData();
498 // external drag&drop doesn't copy objects, so they also aren't deleted:
499 // #105703# bApi=TRUE, don't show error messages from drag&drop
500 pSourceSh->GetDocFunc().DeleteContents( aMarkData, IDF_ALL & ~IDF_OBJECTS, TRUE, TRUE );
504 ScModule* pScMod = SC_MOD();
505 if ( pScMod->GetDragData().pCellTransfer == this )
506 pScMod->ResetDragObject();
508 xDragSourceRanges = NULL; // don't keep source after dropping
510 TransferableHelper::DragFinished( nDropAction );
513 void ScTransferObj::SetDragHandlePos( SCCOL nX, SCROW nY )
515 nDragHandleX = nX;
516 nDragHandleY = nY;
519 void ScTransferObj::SetVisibleTab( SCTAB nNew )
521 nVisibleTab = nNew;
524 void ScTransferObj::SetDrawPersist( const SfxObjectShellRef& rRef )
526 aDrawPersistRef = rRef;
529 void ScTransferObj::SetDragSource( ScDocShell* pSourceShell, const ScMarkData& rMark )
531 ScRangeList aRanges;
532 rMark.FillRangeListWithMarks( &aRanges, FALSE );
533 xDragSourceRanges = new ScCellRangesObj( pSourceShell, aRanges );
536 void ScTransferObj::SetDragSourceFlags( USHORT nFlags )
538 nDragSourceFlags = nFlags;
541 void ScTransferObj::SetDragWasInternal()
543 bDragWasInternal = TRUE;
546 ScDocument* ScTransferObj::GetSourceDocument()
548 ScDocShell* pSourceDocSh = GetSourceDocShell();
549 if (pSourceDocSh)
550 return pSourceDocSh->GetDocument();
551 return NULL;
554 ScDocShell* ScTransferObj::GetSourceDocShell()
556 ScCellRangesBase* pRangesObj = ScCellRangesBase::getImplementation( xDragSourceRanges );
557 if (pRangesObj)
558 return pRangesObj->GetDocShell();
560 return NULL; // none set
563 ScMarkData ScTransferObj::GetSourceMarkData()
565 ScMarkData aMarkData;
566 ScCellRangesBase* pRangesObj = ScCellRangesBase::getImplementation( xDragSourceRanges );
567 if (pRangesObj)
569 const ScRangeList& rRanges = pRangesObj->GetRangeList();
570 aMarkData.MarkFromRangeList( rRanges, FALSE );
572 return aMarkData;
576 // initialize aDocShellRef with a live document from the ClipDoc
579 void ScTransferObj::InitDocShell()
581 if ( !aDocShellRef.Is() )
583 ScDocShell* pDocSh = new ScDocShell;
584 aDocShellRef = pDocSh; // ref must be there before InitNew
586 pDocSh->DoInitNew(NULL);
588 ScDocument* pDestDoc = pDocSh->GetDocument();
589 ScMarkData aDestMark;
590 aDestMark.SelectTable( 0, TRUE );
592 pDestDoc->SetDocOptions( pDoc->GetDocOptions() ); // #i42666#
594 String aTabName;
595 pDoc->GetName( aBlock.aStart.Tab(), aTabName );
596 pDestDoc->RenameTab( 0, aTabName, FALSE ); // no UpdateRef (empty)
598 pDestDoc->CopyStdStylesFrom( pDoc );
600 SCCOL nStartX = aBlock.aStart.Col();
601 SCROW nStartY = aBlock.aStart.Row();
602 SCCOL nEndX = aBlock.aEnd.Col();
603 SCROW nEndY = aBlock.aEnd.Row();
605 // widths / heights
606 // (must be copied before CopyFromClip, for drawing objects)
608 SCCOL nCol, nLastCol;
609 SCROW nRow;
610 SCTAB nSrcTab = aBlock.aStart.Tab();
611 pDestDoc->SetLayoutRTL(0, pDoc->IsLayoutRTL(nSrcTab));
612 for (nCol=nStartX; nCol<=nEndX; nCol++)
613 if ( pDoc->ColHidden(nCol, nSrcTab, nLastCol) )
614 pDestDoc->ShowCol( nCol, 0, FALSE );
615 else
616 pDestDoc->SetColWidth( nCol, 0, pDoc->GetColWidth( nCol, nSrcTab ) );
618 ScBitMaskCompressedArray< SCROW, BYTE> & rDestRowFlags =
619 pDestDoc->GetRowFlagsArrayModifiable(0);
621 for (SCROW nRow = nStartY; nRow <= nEndY; ++nRow)
623 BYTE nSourceFlags = pDoc->GetRowFlags(nRow, nSrcTab);
624 SCROW nLastRow = -1;
625 if ( pDoc->RowHidden(nRow, nSrcTab, nLastRow) )
626 pDestDoc->ShowRow( nRow, 0, FALSE );
627 else
629 pDestDoc->SetRowHeight( nRow, 0, pDoc->GetOriginalHeight( nRow, nSrcTab ) );
631 // if height was set manually, that flag has to be copied, too
632 if ( nSourceFlags & CR_MANUALSIZE )
633 rDestRowFlags.OrValue( nRow, CR_MANUALSIZE);
637 if ( pDoc->GetDrawLayer() )
638 pDocSh->MakeDrawLayer();
640 // cell range is copied to the original position, but on the first sheet
641 // -> bCutMode must be set
642 // pDoc is always a Clipboard-document
644 ScRange aDestRange( nStartX,nStartY,0, nEndX,nEndY,0 );
645 BOOL bWasCut = pDoc->IsCutMode();
646 if (!bWasCut)
647 pDoc->SetClipArea( aDestRange, TRUE ); // Cut
648 pDestDoc->CopyFromClip( aDestRange, aDestMark, IDF_ALL, NULL, pDoc, FALSE );
649 pDoc->SetClipArea( aDestRange, bWasCut );
651 StripRefs( pDoc, nStartX,nStartY, nEndX,nEndY, pDestDoc, 0,0 );
653 ScRange aMergeRange = aDestRange;
654 pDestDoc->ExtendMerge( aMergeRange, TRUE );
656 pDoc->CopyDdeLinks( pDestDoc ); // copy values of DDE Links
658 // page format (grid etc) and page size (maximum size for ole object)
660 Size aPaperSize = SvxPaperInfo::GetPaperSize( PAPER_A4 ); // Twips
661 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
662 String aStyleName = pDoc->GetPageStyle( aBlock.aStart.Tab() );
663 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
664 if (pStyleSheet)
666 const SfxItemSet& rSourceSet = pStyleSheet->GetItemSet();
667 aPaperSize = ((const SvxSizeItem&) rSourceSet.Get(ATTR_PAGE_SIZE)).GetSize();
669 // CopyStyleFrom kopiert SetItems mit richtigem Pool
670 ScStyleSheetPool* pDestPool = pDestDoc->GetStyleSheetPool();
671 pDestPool->CopyStyleFrom( pStylePool, aStyleName, SFX_STYLE_FAMILY_PAGE );
674 ScViewData aViewData( pDocSh, NULL );
675 aViewData.SetScreen( nStartX,nStartY, nEndX,nEndY );
676 aViewData.SetCurX( nStartX );
677 aViewData.SetCurY( nStartY );
679 pDestDoc->SetViewOptions( pDoc->GetViewOptions() );
681 // Size
682 //! get while copying sizes
684 long nPosX = 0;
685 long nPosY = 0;
687 for (nCol=0; nCol<nStartX; nCol++)
688 nPosX += pDestDoc->GetColWidth( nCol, 0 );
689 nPosY += pDestDoc->FastGetRowHeight( 0, nStartY-1, 0 );
690 nPosX = (long) ( nPosX * HMM_PER_TWIPS );
691 nPosY = (long) ( nPosY * HMM_PER_TWIPS );
694 aPaperSize.Width() *= 2; // limit OLE object to double of page size
695 aPaperSize.Height() *= 2;
697 long nSizeX = 0;
698 long nSizeY = 0;
699 for (nCol=nStartX; nCol<=nEndX; nCol++)
701 long nAdd = pDestDoc->GetColWidth( nCol, 0 );
702 if ( nSizeX+nAdd > aPaperSize.Width() && nSizeX ) // above limit?
703 break;
704 nSizeX += nAdd;
706 for (nRow=nStartY; nRow<=nEndY; nRow++)
708 long nAdd = pDestDoc->FastGetRowHeight( nRow, 0 );
709 if ( nSizeY+nAdd > aPaperSize.Height() && nSizeY ) // above limit?
710 break;
711 nSizeY += nAdd;
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 ( pDestDoc->IsChartListenerCollectionNeedsUpdate() )
727 pDestDoc->UpdateChartListenerCollection();
731 // static
732 SfxObjectShell* ScTransferObj::SetDrawClipDoc( BOOL bAnyOle )
734 // update ScGlobal::pDrawClipDocShellRef
736 delete ScGlobal::pDrawClipDocShellRef;
737 if (bAnyOle)
739 ScGlobal::pDrawClipDocShellRef =
740 new ScDocShellRef(new ScDocShell(SFX_CREATE_MODE_INTERNAL)); // there must be a ref
741 (*ScGlobal::pDrawClipDocShellRef)->DoInitNew(NULL);
742 return *ScGlobal::pDrawClipDocShellRef;
744 else
746 ScGlobal::pDrawClipDocShellRef = NULL;
747 return NULL;
751 // static
752 void ScTransferObj::StripRefs( ScDocument* pDoc,
753 SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
754 ScDocument* pDestDoc, SCCOL nSubX, SCROW nSubY )
756 if (!pDestDoc)
758 pDestDoc = pDoc;
759 DBG_ASSERT(nSubX==0&&nSubY==0, "can't move within the document");
762 // In a clipboard doc the data don't have to be on the first sheet
764 SCTAB nSrcTab = 0;
765 while (nSrcTab<MAXTAB && !pDoc->HasTable(nSrcTab))
766 ++nSrcTab;
767 SCTAB nDestTab = 0;
768 while (nDestTab<MAXTAB && !pDestDoc->HasTable(nDestTab))
769 ++nDestTab;
771 if (!pDoc->HasTable(nSrcTab) || !pDestDoc->HasTable(nDestTab))
773 DBG_ERROR("Sheet not found in ScTransferObj::StripRefs");
774 return;
777 SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
778 ScRange aRef;
780 ScCellIterator aIter( pDoc, nStartX, nStartY, nSrcTab, nEndX, nEndY, nSrcTab );
781 ScBaseCell* pCell = aIter.GetFirst();
782 while (pCell)
784 if (pCell->GetCellType() == CELLTYPE_FORMULA)
786 ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
787 BOOL bOut = FALSE;
788 ScDetectiveRefIter aRefIter( pFCell );
789 while ( !bOut && aRefIter.GetNextRef( aRef ) )
791 if ( aRef.aStart.Tab() != nSrcTab || aRef.aEnd.Tab() != nSrcTab ||
792 aRef.aStart.Col() < nStartX || aRef.aEnd.Col() > nEndX ||
793 aRef.aStart.Row() < nStartY || aRef.aEnd.Row() > nEndY )
794 bOut = TRUE;
796 if (bOut)
798 SCCOL nCol = aIter.GetCol() - nSubX;
799 SCROW nRow = aIter.GetRow() - nSubY;
801 ScBaseCell* pNew = 0;
802 USHORT nErrCode = pFCell->GetErrCode();
803 if (nErrCode)
805 pNew = new ScStringCell( ScGlobal::GetErrorString(nErrCode) );
806 if ( ((const SvxHorJustifyItem*) pDestDoc->GetAttr(
807 nCol,nRow,nDestTab, ATTR_HOR_JUSTIFY))->GetValue() ==
808 SVX_HOR_JUSTIFY_STANDARD )
809 pDestDoc->ApplyAttr( nCol,nRow,nDestTab,
810 SvxHorJustifyItem(SVX_HOR_JUSTIFY_RIGHT, ATTR_HOR_JUSTIFY) );
812 else if (pFCell->IsValue())
814 double fVal = pFCell->GetValue();
815 pNew = new ScValueCell( fVal );
817 else
819 String aStr;
820 pFCell->GetString(aStr);
821 if ( pFCell->IsMultilineResult() )
822 pNew = new ScEditCell( aStr, pDestDoc );
823 else
824 pNew = new ScStringCell( aStr );
826 pDestDoc->PutCell( nCol,nRow,nDestTab, pNew );
828 // number formats
830 ULONG nOldFormat = ((const SfxUInt32Item*)
831 pDestDoc->GetAttr(nCol,nRow,nDestTab, ATTR_VALUE_FORMAT))->GetValue();
832 if ( (nOldFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
834 ULONG nNewFormat = pFCell->GetStandardFormat( *pFormatter,
835 nOldFormat );
836 pDestDoc->ApplyAttr( nCol,nRow,nDestTab,
837 SfxUInt32Item(ATTR_VALUE_FORMAT, nNewFormat) );
841 pCell = aIter.GetNext();
845 const com::sun::star::uno::Sequence< sal_Int8 >& ScTransferObj::getUnoTunnelId()
847 static com::sun::star::uno::Sequence< sal_Int8 > aSeq;
848 if( !aSeq.getLength() )
850 static osl::Mutex aCreateMutex;
851 osl::Guard< osl::Mutex > aGuard( aCreateMutex );
852 aSeq.realloc( 16 );
853 rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True );
855 return aSeq;
858 sal_Int64 SAL_CALL ScTransferObj::getSomething( const com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( com::sun::star::uno::RuntimeException )
860 sal_Int64 nRet;
861 if( ( rId.getLength() == 16 ) &&
862 ( 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
864 nRet = reinterpret_cast< sal_Int64 >( this );
866 else
867 nRet = TransferableHelper::getSomething(rId);
868 return nRet;