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