xref: /trunk/main/sc/source/ui/app/drwtrans.cxx (revision b3f79822)
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 
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 
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
279 ScDrawTransferObj* ScDrawTransferObj::GetOwnClipboard( Window* )
280 {
281     ScDrawTransferObj* pObj = SC_MOD()->GetClipData().pDrawClipboard;
282     return pObj;
283 }
284 
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 
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_FORMAT_BITMAP );
322         AddFormat( SOT_FORMAT_GDIMETAFILE );
323     }
324     else if ( bGraphic )        // other graphic
325     {
326 		// #i25616#
327 		AddFormat( SOT_FORMATSTR_ID_DRAWING );
328 
329 		AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
330         AddFormat( SOT_FORMATSTR_ID_SVXB );
331         AddFormat( SOT_FORMAT_GDIMETAFILE );
332         AddFormat( SOT_FORMAT_BITMAP );
333     }
334     else if ( pBookmark )       // url button
335     {
336 //      AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
337         AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
338         AddFormat( SOT_FORMATSTR_ID_SOLK );
339         AddFormat( SOT_FORMAT_STRING );
340         AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR );
341         AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK );
342         AddFormat( SOT_FORMATSTR_ID_DRAWING );
343     }
344     else if ( bOleObj )         // single OLE object
345     {
346         AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
347         AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
348         AddFormat( SOT_FORMAT_GDIMETAFILE );
349 
350         if ( !aOleData.GetTransferable().is() )
351         {
352 			SdrOle2Obj* pObj = GetSingleObject();
353             if ( pObj && pObj->GetObjRef().is() )
354                 aOleData = TransferableDataHelper( new SvEmbedTransferHelper( pObj->GetObjRef(), pObj->GetGraphic(), pObj->GetAspect() ) ) ;
355         }
356         if ( aOleData.GetTransferable().is() )
357         {
358             //  get format list from object snapshot
359             //  (this must be after inserting the default formats!)
360 
361             DataFlavorExVector              aVector( aOleData.GetDataFlavorExVector() );
362             DataFlavorExVector::iterator    aIter( aVector.begin() ), aEnd( aVector.end() );
363 
364             while( aIter != aEnd )
365                 AddFormat( *aIter++ );
366         }
367     }
368     else                        // any drawing objects
369     {
370         AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
371         AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
372         AddFormat( SOT_FORMATSTR_ID_DRAWING );
373 
374         // #103556# leave out bitmap and metafile if there are only controls
375         if ( !lcl_HasOnlyControls( pModel ) )
376         {
377             AddFormat( SOT_FORMAT_BITMAP );
378             AddFormat( SOT_FORMAT_GDIMETAFILE );
379         }
380     }
381 
382 //  if( pImageMap )
383 //      AddFormat( SOT_FORMATSTR_ID_SVIM );
384 }
385 
386 sal_Bool ScDrawTransferObj::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
387 {
388     sal_Bool bOK = sal_False;
389     sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor );
390 
391     if ( bOleObj && nFormat != SOT_FORMAT_GDIMETAFILE )
392     {
393         if ( !aOleData.GetTransferable().is() )
394         {
395 			SdrOle2Obj* pObj = GetSingleObject();
396             if ( pObj && pObj->GetObjRef().is() )
397                 aOleData = TransferableDataHelper( new SvEmbedTransferHelper( pObj->GetObjRef(), pObj->GetGraphic(), pObj->GetAspect() ) ) ;
398         }
399 
400         if( aOleData.GetTransferable().is() && aOleData.HasFormat( rFlavor ) )
401         {
402             sal_uLong nOldSwapMode = 0;
403 
404             if( pModel )
405             {
406                 nOldSwapMode = pModel->GetSwapGraphicsMode();
407                 pModel->SetSwapGraphicsMode( SDR_SWAPGRAPHICSMODE_PURGE );
408             }
409 
410             bOK = SetAny( aOleData.GetAny( rFlavor ), rFlavor );
411 
412             if( pModel )
413                 pModel->SetSwapGraphicsMode( nOldSwapMode );
414 
415             return bOK;
416         }
417     }
418 
419     if( HasFormat( nFormat ) )
420     {
421         if ( nFormat == SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR || nFormat == SOT_FORMATSTR_ID_OBJECTDESCRIPTOR )
422         {
423             bOK = SetTransferableObjectDescriptor( aObjDesc, rFlavor );
424         }
425         else if ( nFormat == SOT_FORMATSTR_ID_DRAWING )
426         {
427             bOK = SetObject( pModel, SCDRAWTRANS_TYPE_DRAWMODEL, rFlavor );
428         }
429         else if ( nFormat == SOT_FORMAT_BITMAP || nFormat == SOT_FORMAT_GDIMETAFILE )
430         {
431 			// #i71538# use complete SdrViews
432             // SdrExchangeView aView( pModel );
433             SdrView aView( pModel );
434             SdrPageView* pPv = aView.ShowSdrPage(aView.GetModel()->GetPage(0));
435             DBG_ASSERT( pPv, "pPv not there..." );
436             aView.MarkAllObj( pPv );
437             if ( nFormat == SOT_FORMAT_GDIMETAFILE )
438                 bOK = SetGDIMetaFile( aView.GetAllMarkedMetaFile( sal_True ), rFlavor );
439             else
440                 bOK = SetBitmap( aView.GetAllMarkedBitmap( sal_True ), rFlavor );
441         }
442         else if ( nFormat == SOT_FORMATSTR_ID_SVXB )
443         {
444             // only enabled for single graphics object
445 
446             SdrPage* pPage = pModel->GetPage(0);
447             if (pPage)
448             {
449                 SdrObjListIter aIter( *pPage, IM_FLAT );
450                 SdrObject* pObject = aIter.Next();
451                 if (pObject && pObject->GetObjIdentifier() == OBJ_GRAF)
452                 {
453                     SdrGrafObj* pGraphObj = (SdrGrafObj*) pObject;
454                     bOK = SetGraphic( pGraphObj->GetGraphic(), rFlavor );
455                 }
456             }
457         }
458         else if ( nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE )
459         {
460             if ( bOleObj )              // single OLE object
461             {
462 				SdrOle2Obj* pObj = GetSingleObject();
463             	if ( pObj && pObj->GetObjRef().is() )
464                 {
465                     bOK = SetObject( pObj->GetObjRef().get(), SCDRAWTRANS_TYPE_EMBOBJ, rFlavor );
466                 }
467             }
468             else                        // create object from contents
469             {
470                 //TODO/LATER: needs new Format, because now single OLE and "this" are different
471                 InitDocShell();         // set aDocShellRef
472 
473                 SfxObjectShell* pEmbObj = aDocShellRef;
474                 bOK = SetObject( pEmbObj, SCDRAWTRANS_TYPE_DOCUMENT, rFlavor );
475             }
476         }
477         else if( pBookmark )
478         {
479             bOK = SetINetBookmark( *pBookmark, rFlavor );
480         }
481     }
482     return bOK;
483 }
484 
485 sal_Bool ScDrawTransferObj::WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId,
486                                         const ::com::sun::star::datatransfer::DataFlavor& /* rFlavor */ )
487 {
488     // called from SetObject, put data into stream
489 
490     sal_Bool bRet = sal_False;
491     switch (nUserObjectId)
492     {
493         case SCDRAWTRANS_TYPE_DRAWMODEL:
494             {
495                 SdrModel* pDrawModel = (SdrModel*)pUserObject;
496                 rxOStm->SetBufferSize( 0xff00 );
497 
498 				// #108584#
499 				// for the changed pool defaults from drawing layer pool set those
500 				// attributes as hard attributes to preserve them for saving
501 				const SfxItemPool& rItemPool = pModel->GetItemPool();
502 				const SvxFontHeightItem& rDefaultFontHeight = (const SvxFontHeightItem&)rItemPool.GetDefaultItem(EE_CHAR_FONTHEIGHT);
503 
504 				// SW should have no MasterPages
505 				DBG_ASSERT(0L == pModel->GetMasterPageCount(), "SW with MasterPages (!)");
506 
507 				for(sal_uInt16 a(0); a < pModel->GetPageCount(); a++)
508 				{
509 					const SdrPage* pPage = pModel->GetPage(a);
510 					SdrObjListIter aIter(*pPage, IM_DEEPNOGROUPS);
511 
512 					while(aIter.IsMore())
513 					{
514 						SdrObject* pObj = aIter.Next();
515 						const SvxFontHeightItem& rItem = (const SvxFontHeightItem&)pObj->GetMergedItem(EE_CHAR_FONTHEIGHT);
516 
517 						if(rItem.GetHeight() == rDefaultFontHeight.GetHeight())
518 						{
519 							pObj->SetMergedItem(rDefaultFontHeight);
520 						}
521 					}
522 				}
523 
524 				{
525 					com::sun::star::uno::Reference<com::sun::star::io::XOutputStream> xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) );
526 					if( SvxDrawingLayerExport( pDrawModel, xDocOut ) )
527 						rxOStm->Commit();
528 				}
529 
530 				bRet = ( rxOStm->GetError() == ERRCODE_NONE );
531             }
532             break;
533 
534         case SCDRAWTRANS_TYPE_EMBOBJ:
535             {
536                 // impl. for "single OLE"
537                 embed::XEmbeddedObject* pEmbObj = (embed::XEmbeddedObject*) pUserObject;
538 
539                 ::utl::TempFile     aTempFile;
540                 aTempFile.EnableKillingFile();
541                 uno::Reference< embed::XStorage > xWorkStore =
542                     ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
543 
544                 uno::Reference < embed::XEmbedPersist > xPers( (embed::XVisualObject*)pEmbObj, uno::UNO_QUERY );
545                 if ( xPers.is() )
546                 {
547                     try
548                     {
549                         uno::Sequence < beans::PropertyValue > aSeq;
550                         ::rtl::OUString aDummyName = ::rtl::OUString::createFromAscii("Dummy");
551                         xPers->storeToEntry( xWorkStore, aDummyName, aSeq, aSeq );
552                         if ( xWorkStore->isStreamElement( aDummyName ) )
553                         {
554                             uno::Reference < io::XOutputStream > xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) );
555                             uno::Reference < io::XStream > xNewStream = xWorkStore->openStreamElement( aDummyName, embed::ElementModes::READ );
556                             ::comphelper::OStorageHelper::CopyInputToOutput( xNewStream->getInputStream(), xDocOut );
557                         }
558                         else
559                         {
560                             uno::Reference < io::XStream > xDocStr( new utl::OStreamWrapper( *rxOStm ) );
561                             uno::Reference< embed::XStorage > xDocStg = ::comphelper::OStorageHelper::GetStorageFromStream( xDocStr );
562                             uno::Reference < embed::XStorage > xNewStg = xWorkStore->openStorageElement( aDummyName, embed::ElementModes::READ );
563                             xNewStg->copyToStorage( xDocStg );
564                             uno::Reference < embed::XTransactedObject > xTrans( xDocStg, uno::UNO_QUERY );
565                             if ( xTrans.is() )
566                                 xTrans->commit();
567                         }
568 
569                         rxOStm->Commit();
570                     }
571                     catch ( uno::Exception& )
572                     {
573                     }
574                 }
575 
576                 break;
577             }
578         case SCDRAWTRANS_TYPE_DOCUMENT:
579             {
580                 // impl. for "DocShell"
581                 SfxObjectShell*   pEmbObj = (SfxObjectShell*) pUserObject;
582 
583                 try
584                 {
585                     ::utl::TempFile     aTempFile;
586                     aTempFile.EnableKillingFile();
587                     uno::Reference< embed::XStorage > xWorkStore =
588                         ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
589 
590                     // write document storage
591                     pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, sal_False );
592 
593                     // mba: no relative ULRs for clipboard!
594                     SfxMedium aMedium( xWorkStore, String() );
595                     bRet = pEmbObj->DoSaveObjectAs( aMedium, sal_False );
596                     pEmbObj->DoSaveCompleted();
597 
598                     uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY );
599                     if ( xTransact.is() )
600                         xTransact->commit();
601 
602                     SvStream* pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), STREAM_READ );
603                     if( pSrcStm )
604                     {
605                         rxOStm->SetBufferSize( 0xff00 );
606                         *rxOStm << *pSrcStm;
607                         delete pSrcStm;
608                     }
609 
610                     bRet = sal_True;
611 
612                     xWorkStore->dispose();
613                     xWorkStore = uno::Reference < embed::XStorage >();
614                     rxOStm->Commit();
615                 }
616                 catch ( uno::Exception& )
617                 {}
618 
619                 bRet = ( rxOStm->GetError() == ERRCODE_NONE );
620             }
621             break;
622 
623         default:
624             DBG_ERROR("unknown object id");
625     }
626     return bRet;
627 }
628 
629 void ScDrawTransferObj::ObjectReleased()
630 {
631     ScModule* pScMod = SC_MOD();
632     if ( pScMod->GetClipData().pDrawClipboard == this )
633         pScMod->SetClipObject( NULL, NULL );
634 
635     TransferableHelper::ObjectReleased();
636 }
637 
638 void ScDrawTransferObj::DragFinished( sal_Int8 nDropAction )
639 {
640     if ( nDropAction == DND_ACTION_MOVE && !bDragWasInternal && !(nDragSourceFlags & SC_DROP_NAVIGATOR) )
641     {
642         //  move: delete source objects
643 
644         if ( pDragSourceView )
645             pDragSourceView->DeleteMarked();
646     }
647 
648     ScModule* pScMod = SC_MOD();
649     if ( pScMod->GetDragData().pDrawTransfer == this )
650         pScMod->ResetDragObject();
651 
652     DELETEZ( pDragSourceView );
653 
654     TransferableHelper::DragFinished( nDropAction );
655 }
656 
657 void ScDrawTransferObj::SetDrawPersist( const SfxObjectShellRef& rRef )
658 {
659     aDrawPersistRef = rRef;
660 }
661 
662 void lcl_InitMarks( SdrMarkView& rDest, const SdrMarkView& rSource, SCTAB nTab )
663 {
664     rDest.ShowSdrPage(rDest.GetModel()->GetPage(nTab));
665     SdrPageView* pDestPV = rDest.GetSdrPageView();
666     DBG_ASSERT(pDestPV,"PageView ?");
667 
668     const SdrMarkList& rMarkList = rSource.GetMarkedObjectList();
669     sal_uLong nCount = rMarkList.GetMarkCount();
670     for (sal_uLong i=0; i<nCount; i++)
671     {
672         SdrMark* pMark = rMarkList.GetMark(i);
673         SdrObject* pObj = pMark->GetMarkedSdrObj();
674 
675         rDest.MarkObj(pObj, pDestPV);
676     }
677 }
678 
679 void ScDrawTransferObj::SetDragSource( ScDrawView* pView )
680 {
681     DELETEZ( pDragSourceView );
682     pDragSourceView = new SdrView( pView->GetModel() );
683     lcl_InitMarks( *pDragSourceView, *pView, pView->GetTab() );
684 
685     //! add as listener with document, delete pDragSourceView if document gone
686 }
687 
688 void ScDrawTransferObj::SetDragSourceObj( SdrObject* pObj, SCTAB nTab )
689 {
690     DELETEZ( pDragSourceView );
691     pDragSourceView = new SdrView( pObj->GetModel() );
692     pDragSourceView->ShowSdrPage(pDragSourceView->GetModel()->GetPage(nTab));
693     SdrPageView* pPV = pDragSourceView->GetSdrPageView();
694     pDragSourceView->MarkObj(pObj, pPV);
695 
696     //! add as listener with document, delete pDragSourceView if document gone
697 }
698 
699 void ScDrawTransferObj::SetDragSourceFlags( sal_uInt16 nFlags )
700 {
701     nDragSourceFlags = nFlags;
702 }
703 
704 void ScDrawTransferObj::SetDragWasInternal()
705 {
706     bDragWasInternal = sal_True;
707 }
708 
709 SdrOle2Obj* ScDrawTransferObj::GetSingleObject()
710 {
711     //  if single OLE object was copied, get its object
712 
713     SdrPage* pPage = pModel->GetPage(0);
714     if (pPage)
715     {
716         SdrObjListIter aIter( *pPage, IM_FLAT );
717         SdrObject* pObject = aIter.Next();
718         if (pObject && pObject->GetObjIdentifier() == OBJ_OLE2)
719         {
720             return (SdrOle2Obj*) pObject;
721         }
722     }
723 
724     return NULL;
725 }
726 
727 //
728 //  initialize aDocShellRef with a live document from the ClipDoc
729 //
730 
731 void ScDrawTransferObj::InitDocShell()
732 {
733     if ( !aDocShellRef.Is() )
734     {
735         ScDocShell* pDocSh = new ScDocShell;
736         aDocShellRef = pDocSh;      // ref must be there before InitNew
737 
738         pDocSh->DoInitNew(NULL);
739 
740         ScDocument* pDestDoc = pDocSh->GetDocument();
741         pDestDoc->InitDrawLayer( pDocSh );
742 
743         SdrModel* pDestModel = pDestDoc->GetDrawLayer();
744 		// #i71538# use complete SdrViews
745         // SdrExchangeView aDestView( pDestModel );
746         SdrView aDestView( pDestModel );
747         aDestView.ShowSdrPage(aDestView.GetModel()->GetPage(0));
748         aDestView.Paste( *pModel, Point( aSrcSize.Width()/2, aSrcSize.Height()/2 ) );
749 
750         // put objects to right layer (see ScViewFunc::PasteDataFormat for SOT_FORMATSTR_ID_DRAWING)
751 
752         SdrPage* pPage = pDestModel->GetPage(0);
753         if (pPage)
754         {
755             SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
756             SdrObject* pObject = aIter.Next();
757             while (pObject)
758             {
759                 if ( pObject->ISA(SdrUnoObj) )
760                     pObject->NbcSetLayer(SC_LAYER_CONTROLS);
761                 else
762                     pObject->NbcSetLayer(SC_LAYER_FRONT);
763                 pObject = aIter.Next();
764             }
765         }
766 
767         Point aTmpPoint;
768         Rectangle aDestArea( aTmpPoint, aSrcSize );
769         pDocSh->SetVisArea( aDestArea );
770 
771         ScViewOptions aViewOpt( pDestDoc->GetViewOptions() );
772         aViewOpt.SetOption( VOPT_GRID, sal_False );
773         pDestDoc->SetViewOptions( aViewOpt );
774 
775         ScViewData aViewData( pDocSh, NULL );
776         aViewData.SetTabNo( 0 );
777         aViewData.SetScreen( aDestArea );
778         aViewData.SetCurX( 0 );
779         aViewData.SetCurY( 0 );
780         pDocSh->UpdateOle(&aViewData, sal_True);
781     }
782 }
783 
784 const com::sun::star::uno::Sequence< sal_Int8 >& ScDrawTransferObj::getUnoTunnelId()
785 {
786     static com::sun::star::uno::Sequence< sal_Int8 > aSeq;
787     if( !aSeq.getLength() )
788     {
789         static osl::Mutex           aCreateMutex;
790         osl::Guard< osl::Mutex >    aGuard( aCreateMutex );
791         aSeq.realloc( 16 );
792         rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True );
793     }
794     return aSeq;
795 }
796 
797 sal_Int64 SAL_CALL ScDrawTransferObj::getSomething( const com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( com::sun::star::uno::RuntimeException )
798 {
799     sal_Int64 nRet;
800     if( ( rId.getLength() == 16 ) &&
801         ( 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
802     {
803         nRet = reinterpret_cast< sal_Int64 >( this );
804     }
805     else
806         nRet = TransferableHelper::getSomething(rId);
807     return nRet;
808 }
809 
810 
811