xref: /aoo42x/main/sc/source/ui/app/drwtrans.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 // INCLUDE ---------------------------------------------------------------
32 
33 
34 #include <com/sun/star/embed/XTransactedObject.hpp>
35 #include <com/sun/star/embed/XEmbedPersist.hpp>
36 #include <com/sun/star/uno/Exception.hpp>
37 
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/beans/XPropertySetInfo.hpp>
40 #include <com/sun/star/form/FormButtonType.hpp>
41 #include <toolkit/helper/vclunohelper.hxx>
42 #include <unotools/streamwrap.hxx>
43 
44 #include <svx/unomodel.hxx>
45 #include <unotools/tempfile.hxx>
46 #include <unotools/ucbstreamhelper.hxx>
47 #include <comphelper/storagehelper.hxx>
48 
49 #include <svtools/embedtransfer.hxx>
50 #include <sot/storage.hxx>
51 #include <vcl/virdev.hxx>
52 #include <svx/fmglob.hxx>
53 #include <svx/svditer.hxx>
54 #include <svx/svdograf.hxx>
55 #include <svx/svdoole2.hxx>
56 #include <svx/svdouno.hxx>
57 #include <svx/svdpage.hxx>
58 #include <svx/svdxcgv.hxx>
59 #include <sfx2/docfile.hxx>
60 #include <svl/itempool.hxx>
61 #include <svl/urlbmk.hxx>
62 #include <tools/urlobj.hxx>
63 #include <vos/mutex.hxx>
64 
65 #include "drwtrans.hxx"
66 #include "docsh.hxx"
67 #include "drwlayer.hxx"
68 #include "drawview.hxx"
69 #include "viewdata.hxx"
70 #include "scmod.hxx"
71 #include "chartlis.hxx"
72 #include "rangeutl.hxx"
73 #include "formula/grammar.hxx"
74 
75 // #108584#
76 #include "scitems.hxx"
77 
78 // #108584#
79 #include <editeng/eeitem.hxx>
80 
81 // #108584#
82 #include <editeng/fhgtitem.hxx>
83 #include <vcl/svapp.hxx>
84 
85 
86 using namespace com::sun::star;
87 
88 // -----------------------------------------------------------------------
89 
90 #define SCDRAWTRANS_TYPE_EMBOBJ         1
91 #define SCDRAWTRANS_TYPE_DRAWMODEL      2
92 #define SCDRAWTRANS_TYPE_DOCUMENT       3
93 
94 // -----------------------------------------------------------------------
95 
96 // -----------------------------------------------------------------------
97 
98 ScDrawTransferObj::ScDrawTransferObj( SdrModel* pClipModel, ScDocShell* pContainerShell,
99                                         const TransferableObjectDescriptor& rDesc ) :
100     pModel( pClipModel ),
101     aObjDesc( rDesc ),
102     pBookmark( NULL ),
103     bGraphic( sal_False ),
104     bGrIsBit( sal_False ),
105     bOleObj( sal_False ),
106     pDragSourceView( NULL ),
107     nDragSourceFlags( 0 ),
108     bDragWasInternal( sal_False ),
109     nSourceDocID( 0 )
110 {
111     //
112     //  check what kind of objects are contained
113     //
114 
115     SdrPage* pPage = pModel->GetPage(0);
116     if (pPage)
117     {
118         SdrObjListIter aIter( *pPage, IM_FLAT );
119         SdrObject* pObject = aIter.Next();
120         if (pObject && !aIter.Next())               // exactly one object?
121         {
122             //
123             //  OLE object
124             //
125 
126             sal_uInt16 nSdrObjKind = pObject->GetObjIdentifier();
127             if (nSdrObjKind == OBJ_OLE2)
128             {
129 				// if object has no persistence it must be copied as a part of document
130 				try
131 				{
132 					uno::Reference< embed::XEmbedPersist > xPersObj( ((SdrOle2Obj*)pObject)->GetObjRef(), uno::UNO_QUERY );
133 					if ( xPersObj.is() && xPersObj->hasEntry() )
134                 		bOleObj = sal_True;
135 				}
136 				catch( uno::Exception& )
137 				{}
138                 // aOleData is initialized later
139             }
140 
141             //
142             //  Graphic object
143             //
144 
145             if (nSdrObjKind == OBJ_GRAF)
146             {
147                 bGraphic = sal_True;
148                 if ( ((SdrGrafObj*)pObject)->GetGraphic().GetType() == GRAPHIC_BITMAP )
149                     bGrIsBit = sal_True;
150             }
151 
152             //
153             //  URL button
154             //
155 
156             SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, pObject);
157             if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor())
158             {
159                 uno::Reference<awt::XControlModel> xControlModel = pUnoCtrl->GetUnoControlModel();
160                 DBG_ASSERT( xControlModel.is(), "uno control without model" );
161                 if ( xControlModel.is() )
162                 {
163                     uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
164                     uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo();
165 
166                     rtl::OUString sPropButtonType = rtl::OUString::createFromAscii( "ButtonType" );
167                     rtl::OUString sPropTargetURL  = rtl::OUString::createFromAscii( "TargetURL" );
168                     rtl::OUString sPropLabel      = rtl::OUString::createFromAscii( "Label" );
169 
170                     if(xInfo->hasPropertyByName( sPropButtonType ))
171                     {
172                         uno::Any aAny = xPropSet->getPropertyValue( sPropButtonType );
173                         form::FormButtonType eTmp;
174                         if ( (aAny >>= eTmp) && eTmp == form::FormButtonType_URL )
175                         {
176                             // URL
177                             if(xInfo->hasPropertyByName( sPropTargetURL ))
178                             {
179                                 aAny = xPropSet->getPropertyValue( sPropTargetURL );
180                                 rtl::OUString sTmp;
181                                 if ( (aAny >>= sTmp) && sTmp.getLength() )
182                                 {
183                                     String aUrl = sTmp;
184                                     String aAbs;
185                                     const SfxMedium* pMedium;
186                                     if (pContainerShell && (pMedium = pContainerShell->GetMedium()) != NULL)
187                                     {
188                                         bool bWasAbs = true;
189                                         aAbs = pMedium->GetURLObject().smartRel2Abs( aUrl, bWasAbs ).
190                                         			GetMainURL(INetURLObject::NO_DECODE);
191 										// full path as stored INetBookmark must be encoded
192                                     }
193                                     else
194                                         aAbs = aUrl;
195 
196                                     // Label
197                                     String aLabel;
198                                     if(xInfo->hasPropertyByName( sPropLabel ))
199                                     {
200                                         aAny = xPropSet->getPropertyValue( sPropLabel );
201                                         if ( (aAny >>= sTmp) && sTmp.getLength() )
202                                         {
203                                             aLabel = String(sTmp);
204                                         }
205                                     }
206                                     pBookmark = new INetBookmark( aAbs, aLabel );
207                                 }
208                             }
209                         }
210                     }
211                 }
212             }
213         }
214     }
215 
216     //
217     //  get size for object descriptor
218     //
219 
220 	// #i71538# use complete SdrViews
221     // SdrExchangeView aView(pModel);
222     SdrView aView(pModel);
223     SdrPageView* pPv = aView.ShowSdrPage(aView.GetModel()->GetPage(0));
224     aView.MarkAllObj(pPv);
225     aSrcSize = aView.GetAllMarkedRect().GetSize();
226 
227     if ( bOleObj )              // single OLE object
228     {
229 		SdrOle2Obj* pObj = GetSingleObject();
230     	if ( pObj && pObj->GetObjRef().is() )
231             SvEmbedTransferHelper::FillTransferableObjectDescriptor( aObjDesc, pObj->GetObjRef(), pObj->GetGraphic(), pObj->GetAspect() );
232     }
233 
234     aObjDesc.maSize = aSrcSize;
235     PrepareOLE( aObjDesc );
236 
237     //
238     // remember a unique ID of the source document
239     //
240     if ( pContainerShell )
241     {
242         ScDocument* pDoc = pContainerShell->GetDocument();
243         if ( pDoc )
244         {
245             nSourceDocID = pDoc->GetDocumentID();
246             if ( pPage )
247             {
248                 ScChartHelper::FillProtectedChartRangesVector( m_aProtectedChartRangesVector, pDoc, pPage );
249             }
250         }
251     }
252 }
253 
254 ScDrawTransferObj::~ScDrawTransferObj()
255 {
256     Application::GetSolarMutex().acquire();     //! ???
257 
258     ScModule* pScMod = SC_MOD();
259     if ( pScMod->GetClipData().pDrawClipboard == this )
260     {
261         DBG_ERROR("ScDrawTransferObj wasn't released");
262         pScMod->SetClipObject( NULL, NULL );
263     }
264     if ( pScMod->GetDragData().pDrawTransfer == this )
265     {
266         DBG_ERROR("ScDrawTransferObj wasn't released");
267         pScMod->ResetDragObject();
268     }
269 
270     aOleData = TransferableDataHelper();        // clear before releasing the mutex
271     aDocShellRef.Clear();
272 
273     delete pModel;
274     aDrawPersistRef.Clear();                    // after the model
275 
276     delete pBookmark;
277     delete pDragSourceView;
278 
279     Application::GetSolarMutex().release();     //! ???
280 }
281 
282 // static
283 ScDrawTransferObj* ScDrawTransferObj::GetOwnClipboard( Window* )
284 {
285     ScDrawTransferObj* pObj = SC_MOD()->GetClipData().pDrawClipboard;
286     return pObj;
287 }
288 
289 sal_Bool lcl_HasOnlyControls( SdrModel* pModel )
290 {
291     sal_Bool bOnlyControls = sal_False;         // default if there are no objects
292 
293     if ( pModel )
294     {
295         SdrPage* pPage = pModel->GetPage(0);
296         if (pPage)
297         {
298             SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
299             SdrObject* pObj = aIter.Next();
300             if ( pObj )
301             {
302                 bOnlyControls = sal_True;   // only set if there are any objects at all
303                 while ( pObj )
304                 {
305                     if (!pObj->ISA(SdrUnoObj))
306                     {
307                         bOnlyControls = sal_False;
308                         break;
309                     }
310                     pObj = aIter.Next();
311                 }
312             }
313         }
314     }
315 
316     return bOnlyControls;
317 }
318 
319 void ScDrawTransferObj::AddSupportedFormats()
320 {
321     if ( bGrIsBit )             // single bitmap graphic
322     {
323 		AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
324         AddFormat( SOT_FORMATSTR_ID_SVXB );
325         AddFormat( SOT_FORMAT_BITMAP );
326         AddFormat( SOT_FORMAT_GDIMETAFILE );
327     }
328     else if ( bGraphic )        // other graphic
329     {
330 		// #i25616#
331 		AddFormat( SOT_FORMATSTR_ID_DRAWING );
332 
333 		AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
334         AddFormat( SOT_FORMATSTR_ID_SVXB );
335         AddFormat( SOT_FORMAT_GDIMETAFILE );
336         AddFormat( SOT_FORMAT_BITMAP );
337     }
338     else if ( pBookmark )       // url button
339     {
340 //      AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
341         AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
342         AddFormat( SOT_FORMATSTR_ID_SOLK );
343         AddFormat( SOT_FORMAT_STRING );
344         AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR );
345         AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK );
346         AddFormat( SOT_FORMATSTR_ID_DRAWING );
347     }
348     else if ( bOleObj )         // single OLE object
349     {
350         AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
351         AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
352         AddFormat( SOT_FORMAT_GDIMETAFILE );
353 
354         if ( !aOleData.GetTransferable().is() )
355         {
356 			SdrOle2Obj* pObj = GetSingleObject();
357             if ( pObj && pObj->GetObjRef().is() )
358                 aOleData = TransferableDataHelper( new SvEmbedTransferHelper( pObj->GetObjRef(), pObj->GetGraphic(), pObj->GetAspect() ) ) ;
359         }
360         if ( aOleData.GetTransferable().is() )
361         {
362             //  get format list from object snapshot
363             //  (this must be after inserting the default formats!)
364 
365             DataFlavorExVector              aVector( aOleData.GetDataFlavorExVector() );
366             DataFlavorExVector::iterator    aIter( aVector.begin() ), aEnd( aVector.end() );
367 
368             while( aIter != aEnd )
369                 AddFormat( *aIter++ );
370         }
371     }
372     else                        // any drawing objects
373     {
374         AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
375         AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
376         AddFormat( SOT_FORMATSTR_ID_DRAWING );
377 
378         // #103556# leave out bitmap and metafile if there are only controls
379         if ( !lcl_HasOnlyControls( pModel ) )
380         {
381             AddFormat( SOT_FORMAT_BITMAP );
382             AddFormat( SOT_FORMAT_GDIMETAFILE );
383         }
384     }
385 
386 //  if( pImageMap )
387 //      AddFormat( SOT_FORMATSTR_ID_SVIM );
388 }
389 
390 sal_Bool ScDrawTransferObj::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
391 {
392     sal_Bool bOK = sal_False;
393     sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor );
394 
395     if ( bOleObj && nFormat != SOT_FORMAT_GDIMETAFILE )
396     {
397         if ( !aOleData.GetTransferable().is() )
398         {
399 			SdrOle2Obj* pObj = GetSingleObject();
400             if ( pObj && pObj->GetObjRef().is() )
401                 aOleData = TransferableDataHelper( new SvEmbedTransferHelper( pObj->GetObjRef(), pObj->GetGraphic(), pObj->GetAspect() ) ) ;
402         }
403 
404         if( aOleData.GetTransferable().is() && aOleData.HasFormat( rFlavor ) )
405         {
406             sal_uLong nOldSwapMode = 0;
407 
408             if( pModel )
409             {
410                 nOldSwapMode = pModel->GetSwapGraphicsMode();
411                 pModel->SetSwapGraphicsMode( SDR_SWAPGRAPHICSMODE_PURGE );
412             }
413 
414             bOK = SetAny( aOleData.GetAny( rFlavor ), rFlavor );
415 
416             if( pModel )
417                 pModel->SetSwapGraphicsMode( nOldSwapMode );
418 
419             return bOK;
420         }
421     }
422 
423     if( HasFormat( nFormat ) )
424     {
425         if ( nFormat == SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR || nFormat == SOT_FORMATSTR_ID_OBJECTDESCRIPTOR )
426         {
427             bOK = SetTransferableObjectDescriptor( aObjDesc, rFlavor );
428         }
429         else if ( nFormat == SOT_FORMATSTR_ID_DRAWING )
430         {
431             bOK = SetObject( pModel, SCDRAWTRANS_TYPE_DRAWMODEL, rFlavor );
432         }
433         else if ( nFormat == SOT_FORMAT_BITMAP || nFormat == SOT_FORMAT_GDIMETAFILE )
434         {
435 			// #i71538# use complete SdrViews
436             // SdrExchangeView aView( pModel );
437             SdrView aView( pModel );
438             SdrPageView* pPv = aView.ShowSdrPage(aView.GetModel()->GetPage(0));
439             DBG_ASSERT( pPv, "pPv not there..." );
440             aView.MarkAllObj( pPv );
441             if ( nFormat == SOT_FORMAT_GDIMETAFILE )
442                 bOK = SetGDIMetaFile( aView.GetAllMarkedMetaFile( sal_True ), rFlavor );
443             else
444                 bOK = SetBitmap( aView.GetAllMarkedBitmap( sal_True ), rFlavor );
445         }
446         else if ( nFormat == SOT_FORMATSTR_ID_SVXB )
447         {
448             // only enabled for single graphics object
449 
450             SdrPage* pPage = pModel->GetPage(0);
451             if (pPage)
452             {
453                 SdrObjListIter aIter( *pPage, IM_FLAT );
454                 SdrObject* pObject = aIter.Next();
455                 if (pObject && pObject->GetObjIdentifier() == OBJ_GRAF)
456                 {
457                     SdrGrafObj* pGraphObj = (SdrGrafObj*) pObject;
458                     bOK = SetGraphic( pGraphObj->GetGraphic(), rFlavor );
459                 }
460             }
461         }
462         else if ( nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE )
463         {
464             if ( bOleObj )              // single OLE object
465             {
466 				SdrOle2Obj* pObj = GetSingleObject();
467             	if ( pObj && pObj->GetObjRef().is() )
468                 {
469                     bOK = SetObject( pObj->GetObjRef().get(), SCDRAWTRANS_TYPE_EMBOBJ, rFlavor );
470                 }
471             }
472             else                        // create object from contents
473             {
474                 //TODO/LATER: needs new Format, because now single OLE and "this" are different
475                 InitDocShell();         // set aDocShellRef
476 
477                 SfxObjectShell* pEmbObj = aDocShellRef;
478                 bOK = SetObject( pEmbObj, SCDRAWTRANS_TYPE_DOCUMENT, rFlavor );
479             }
480         }
481         else if( pBookmark )
482         {
483             bOK = SetINetBookmark( *pBookmark, rFlavor );
484         }
485     }
486     return bOK;
487 }
488 
489 sal_Bool ScDrawTransferObj::WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId,
490                                         const ::com::sun::star::datatransfer::DataFlavor& /* rFlavor */ )
491 {
492     // called from SetObject, put data into stream
493 
494     sal_Bool bRet = sal_False;
495     switch (nUserObjectId)
496     {
497         case SCDRAWTRANS_TYPE_DRAWMODEL:
498             {
499                 SdrModel* pDrawModel = (SdrModel*)pUserObject;
500                 rxOStm->SetBufferSize( 0xff00 );
501 
502 				// #108584#
503 				// for the changed pool defaults from drawing layer pool set those
504 				// attributes as hard attributes to preserve them for saving
505 				const SfxItemPool& rItemPool = pModel->GetItemPool();
506 				const SvxFontHeightItem& rDefaultFontHeight = (const SvxFontHeightItem&)rItemPool.GetDefaultItem(EE_CHAR_FONTHEIGHT);
507 
508 				// SW should have no MasterPages
509 				DBG_ASSERT(0L == pModel->GetMasterPageCount(), "SW with MasterPages (!)");
510 
511 				for(sal_uInt16 a(0); a < pModel->GetPageCount(); a++)
512 				{
513 					const SdrPage* pPage = pModel->GetPage(a);
514 					SdrObjListIter aIter(*pPage, IM_DEEPNOGROUPS);
515 
516 					while(aIter.IsMore())
517 					{
518 						SdrObject* pObj = aIter.Next();
519 						const SvxFontHeightItem& rItem = (const SvxFontHeightItem&)pObj->GetMergedItem(EE_CHAR_FONTHEIGHT);
520 
521 						if(rItem.GetHeight() == rDefaultFontHeight.GetHeight())
522 						{
523 							pObj->SetMergedItem(rDefaultFontHeight);
524 						}
525 					}
526 				}
527 
528 				{
529 					com::sun::star::uno::Reference<com::sun::star::io::XOutputStream> xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) );
530 					if( SvxDrawingLayerExport( pDrawModel, xDocOut ) )
531 						rxOStm->Commit();
532 				}
533 
534 				bRet = ( rxOStm->GetError() == ERRCODE_NONE );
535             }
536             break;
537 
538         case SCDRAWTRANS_TYPE_EMBOBJ:
539             {
540                 // impl. for "single OLE"
541                 embed::XEmbeddedObject* pEmbObj = (embed::XEmbeddedObject*) pUserObject;
542 
543                 ::utl::TempFile     aTempFile;
544                 aTempFile.EnableKillingFile();
545                 uno::Reference< embed::XStorage > xWorkStore =
546                     ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
547 
548                 uno::Reference < embed::XEmbedPersist > xPers( (embed::XVisualObject*)pEmbObj, uno::UNO_QUERY );
549                 if ( xPers.is() )
550                 {
551                     try
552                     {
553                         uno::Sequence < beans::PropertyValue > aSeq;
554                         ::rtl::OUString aDummyName = ::rtl::OUString::createFromAscii("Dummy");
555                         xPers->storeToEntry( xWorkStore, aDummyName, aSeq, aSeq );
556                         if ( xWorkStore->isStreamElement( aDummyName ) )
557                         {
558                             uno::Reference < io::XOutputStream > xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) );
559                             uno::Reference < io::XStream > xNewStream = xWorkStore->openStreamElement( aDummyName, embed::ElementModes::READ );
560                             ::comphelper::OStorageHelper::CopyInputToOutput( xNewStream->getInputStream(), xDocOut );
561                         }
562                         else
563                         {
564                             uno::Reference < io::XStream > xDocStr( new utl::OStreamWrapper( *rxOStm ) );
565                             uno::Reference< embed::XStorage > xDocStg = ::comphelper::OStorageHelper::GetStorageFromStream( xDocStr );
566                             uno::Reference < embed::XStorage > xNewStg = xWorkStore->openStorageElement( aDummyName, embed::ElementModes::READ );
567                             xNewStg->copyToStorage( xDocStg );
568                             uno::Reference < embed::XTransactedObject > xTrans( xDocStg, uno::UNO_QUERY );
569                             if ( xTrans.is() )
570                                 xTrans->commit();
571                         }
572 
573                         rxOStm->Commit();
574                     }
575                     catch ( uno::Exception& )
576                     {
577                     }
578                 }
579 
580                 break;
581             }
582         case SCDRAWTRANS_TYPE_DOCUMENT:
583             {
584                 // impl. for "DocShell"
585                 SfxObjectShell*   pEmbObj = (SfxObjectShell*) pUserObject;
586 
587                 try
588                 {
589                     ::utl::TempFile     aTempFile;
590                     aTempFile.EnableKillingFile();
591                     uno::Reference< embed::XStorage > xWorkStore =
592                         ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
593 
594                     // write document storage
595                     pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, sal_False );
596 
597                     // mba: no relative ULRs for clipboard!
598                     SfxMedium aMedium( xWorkStore, String() );
599                     bRet = pEmbObj->DoSaveObjectAs( aMedium, sal_False );
600                     pEmbObj->DoSaveCompleted();
601 
602                     uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY );
603                     if ( xTransact.is() )
604                         xTransact->commit();
605 
606                     SvStream* pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), STREAM_READ );
607                     if( pSrcStm )
608                     {
609                         rxOStm->SetBufferSize( 0xff00 );
610                         *rxOStm << *pSrcStm;
611                         delete pSrcStm;
612                     }
613 
614                     bRet = sal_True;
615 
616                     xWorkStore->dispose();
617                     xWorkStore = uno::Reference < embed::XStorage >();
618                     rxOStm->Commit();
619                 }
620                 catch ( uno::Exception& )
621                 {}
622 
623                 bRet = ( rxOStm->GetError() == ERRCODE_NONE );
624             }
625             break;
626 
627         default:
628             DBG_ERROR("unknown object id");
629     }
630     return bRet;
631 }
632 
633 void ScDrawTransferObj::ObjectReleased()
634 {
635     ScModule* pScMod = SC_MOD();
636     if ( pScMod->GetClipData().pDrawClipboard == this )
637         pScMod->SetClipObject( NULL, NULL );
638 
639     TransferableHelper::ObjectReleased();
640 }
641 
642 void ScDrawTransferObj::DragFinished( sal_Int8 nDropAction )
643 {
644     if ( nDropAction == DND_ACTION_MOVE && !bDragWasInternal && !(nDragSourceFlags & SC_DROP_NAVIGATOR) )
645     {
646         //  move: delete source objects
647 
648         if ( pDragSourceView )
649             pDragSourceView->DeleteMarked();
650     }
651 
652     ScModule* pScMod = SC_MOD();
653     if ( pScMod->GetDragData().pDrawTransfer == this )
654         pScMod->ResetDragObject();
655 
656     DELETEZ( pDragSourceView );
657 
658     TransferableHelper::DragFinished( nDropAction );
659 }
660 
661 void ScDrawTransferObj::SetDrawPersist( const SfxObjectShellRef& rRef )
662 {
663     aDrawPersistRef = rRef;
664 }
665 
666 void lcl_InitMarks( SdrMarkView& rDest, const SdrMarkView& rSource, SCTAB nTab )
667 {
668     rDest.ShowSdrPage(rDest.GetModel()->GetPage(nTab));
669     SdrPageView* pDestPV = rDest.GetSdrPageView();
670     DBG_ASSERT(pDestPV,"PageView ?");
671 
672     const SdrMarkList& rMarkList = rSource.GetMarkedObjectList();
673     sal_uLong nCount = rMarkList.GetMarkCount();
674     for (sal_uLong i=0; i<nCount; i++)
675     {
676         SdrMark* pMark = rMarkList.GetMark(i);
677         SdrObject* pObj = pMark->GetMarkedSdrObj();
678 
679         rDest.MarkObj(pObj, pDestPV);
680     }
681 }
682 
683 void ScDrawTransferObj::SetDragSource( ScDrawView* pView )
684 {
685     DELETEZ( pDragSourceView );
686     pDragSourceView = new SdrView( pView->GetModel() );
687     lcl_InitMarks( *pDragSourceView, *pView, pView->GetTab() );
688 
689     //! add as listener with document, delete pDragSourceView if document gone
690 }
691 
692 void ScDrawTransferObj::SetDragSourceObj( SdrObject* pObj, SCTAB nTab )
693 {
694     DELETEZ( pDragSourceView );
695     pDragSourceView = new SdrView( pObj->GetModel() );
696     pDragSourceView->ShowSdrPage(pDragSourceView->GetModel()->GetPage(nTab));
697     SdrPageView* pPV = pDragSourceView->GetSdrPageView();
698     pDragSourceView->MarkObj(pObj, pPV);
699 
700     //! add as listener with document, delete pDragSourceView if document gone
701 }
702 
703 void ScDrawTransferObj::SetDragSourceFlags( sal_uInt16 nFlags )
704 {
705     nDragSourceFlags = nFlags;
706 }
707 
708 void ScDrawTransferObj::SetDragWasInternal()
709 {
710     bDragWasInternal = sal_True;
711 }
712 
713 SdrOle2Obj* ScDrawTransferObj::GetSingleObject()
714 {
715     //  if single OLE object was copied, get its object
716 
717     SdrPage* pPage = pModel->GetPage(0);
718     if (pPage)
719     {
720         SdrObjListIter aIter( *pPage, IM_FLAT );
721         SdrObject* pObject = aIter.Next();
722         if (pObject && pObject->GetObjIdentifier() == OBJ_OLE2)
723         {
724             return (SdrOle2Obj*) pObject;
725         }
726     }
727 
728     return NULL;
729 }
730 
731 //
732 //  initialize aDocShellRef with a live document from the ClipDoc
733 //
734 
735 void ScDrawTransferObj::InitDocShell()
736 {
737     if ( !aDocShellRef.Is() )
738     {
739         ScDocShell* pDocSh = new ScDocShell;
740         aDocShellRef = pDocSh;      // ref must be there before InitNew
741 
742         pDocSh->DoInitNew(NULL);
743 
744         ScDocument* pDestDoc = pDocSh->GetDocument();
745         pDestDoc->InitDrawLayer( pDocSh );
746 
747         SdrModel* pDestModel = pDestDoc->GetDrawLayer();
748 		// #i71538# use complete SdrViews
749         // SdrExchangeView aDestView( pDestModel );
750         SdrView aDestView( pDestModel );
751         aDestView.ShowSdrPage(aDestView.GetModel()->GetPage(0));
752         aDestView.Paste( *pModel, Point( aSrcSize.Width()/2, aSrcSize.Height()/2 ) );
753 
754         // put objects to right layer (see ScViewFunc::PasteDataFormat for SOT_FORMATSTR_ID_DRAWING)
755 
756         SdrPage* pPage = pDestModel->GetPage(0);
757         if (pPage)
758         {
759             SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
760             SdrObject* pObject = aIter.Next();
761             while (pObject)
762             {
763                 if ( pObject->ISA(SdrUnoObj) )
764                     pObject->NbcSetLayer(SC_LAYER_CONTROLS);
765                 else
766                     pObject->NbcSetLayer(SC_LAYER_FRONT);
767                 pObject = aIter.Next();
768             }
769         }
770 
771         Point aTmpPoint;
772         Rectangle aDestArea( aTmpPoint, aSrcSize );
773         pDocSh->SetVisArea( aDestArea );
774 
775         ScViewOptions aViewOpt( pDestDoc->GetViewOptions() );
776         aViewOpt.SetOption( VOPT_GRID, sal_False );
777         pDestDoc->SetViewOptions( aViewOpt );
778 
779         ScViewData aViewData( pDocSh, NULL );
780         aViewData.SetTabNo( 0 );
781         aViewData.SetScreen( aDestArea );
782         aViewData.SetCurX( 0 );
783         aViewData.SetCurY( 0 );
784         pDocSh->UpdateOle(&aViewData, sal_True);
785     }
786 }
787 
788 const com::sun::star::uno::Sequence< sal_Int8 >& ScDrawTransferObj::getUnoTunnelId()
789 {
790     static com::sun::star::uno::Sequence< sal_Int8 > aSeq;
791     if( !aSeq.getLength() )
792     {
793         static osl::Mutex           aCreateMutex;
794         osl::Guard< osl::Mutex >    aGuard( aCreateMutex );
795         aSeq.realloc( 16 );
796         rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True );
797     }
798     return aSeq;
799 }
800 
801 sal_Int64 SAL_CALL ScDrawTransferObj::getSomething( const com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( com::sun::star::uno::RuntimeException )
802 {
803     sal_Int64 nRet;
804     if( ( rId.getLength() == 16 ) &&
805         ( 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
806     {
807         nRet = reinterpret_cast< sal_Int64 >( this );
808     }
809     else
810         nRet = TransferableHelper::getSomething(rId);
811     return nRet;
812 }
813 
814 
815