xref: /trunk/main/sd/source/ui/app/sdxfer.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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_sd.hxx"
30 #include <com/sun/star/embed/XTransactedObject.hpp>
31 #include <com/sun/star/embed/XEmbedPersist.hpp>
32 #include <com/sun/star/embed/ElementModes.hpp>
33 #include <com/sun/star/lang/XComponent.hpp>
34 #include <vos/mutex.hxx>
35 #include <unotools/ucbstreamhelper.hxx>
36 #ifndef _UNTOOLS_TEMPFILE_HXX
37 #include <unotools/tempfile.hxx>
38 #endif
39 #include <editeng/eeitem.hxx>
40 #include <editeng/flditem.hxx>
41 #include <svx/svdpagv.hxx>
42 #include <sfx2/app.hxx>
43 #include <vcl/msgbox.hxx>
44 #include <svx/svdoole2.hxx>
45 #include <svx/svdograf.hxx>
46 #include <svx/svdotext.hxx>
47 #include <editeng/outlobj.hxx>
48 #include <sot/storage.hxx>
49 #include <svl/itempool.hxx>
50 #include <editeng/editobj.hxx>
51 #include <svx/fmglob.hxx>
52 #include <svx/svdouno.hxx>
53 #include <tools/urlobj.hxx>
54 #include <sot/formats.hxx>
55 #include <svl/urlbmk.hxx>
56 #include <editeng/outliner.hxx>
57 
58 //#ifndef _SVDETC_HXX //autogen
59 //#include <svx/svdetc.hxx>
60 //#endif
61 #include <com/sun/star/form/FormButtonType.hpp>
62 #include <com/sun/star/beans/XPropertySet.hpp>
63 #include <unotools/streamwrap.hxx>
64 
65 #include <svx/svdotable.hxx>
66 #include <svx/unomodel.hxx>
67 #include <svx/svditer.hxx>
68 #include <sfx2/docfile.hxx>
69 #include <comphelper/storagehelper.hxx>
70 #include <svtools/embedtransfer.hxx>
71 #include "DrawDocShell.hxx"
72 #include "View.hxx"
73 #include "sdpage.hxx"
74 #include "drawview.hxx"
75 #include "drawdoc.hxx"
76 #include "stlpool.hxx"
77 #include "strings.hrc"
78 #include "sdresid.hxx"
79 #include "imapinfo.hxx"
80 #include "sdxfer.hxx"
81 #include "unomodel.hxx"
82 #include <vcl/virdev.hxx>
83 
84 // --------------
85 // - Namespaces -
86 // --------------
87 
88 using namespace ::com::sun::star;
89 using namespace ::com::sun::star::lang;
90 using namespace ::com::sun::star::uno;
91 using namespace ::com::sun::star::io;
92 using namespace ::com::sun::star::datatransfer;
93 using namespace ::com::sun::star::datatransfer::clipboard;
94 
95 // -----------
96 // - Defines -
97 // -----------
98 
99 #define SDTRANSFER_OBJECTTYPE_DRAWMODEL         0x00000001
100 #define SDTRANSFER_OBJECTTYPE_DRAWOLE           0x00000002
101 
102 // ------------------
103 // - SdTransferable -
104 // ------------------
105 
106 SdTransferable::SdTransferable( SdDrawDocument* pSrcDoc, ::sd::View* pWorkView, sal_Bool bInitOnGetData )
107 :   mpPageDocShell( NULL )
108 ,   mpOLEDataHelper( NULL )
109 ,   mpObjDesc( NULL )
110 ,   mpSdView( pWorkView )
111 ,   mpSdViewIntern( pWorkView )
112 ,   mpSdDrawDocument( NULL )
113 ,   mpSdDrawDocumentIntern( NULL )
114 ,   mpSourceDoc( pSrcDoc )
115 ,   mpVDev( NULL )
116 ,   mpBookmark( NULL )
117 ,   mpGraphic( NULL )
118 ,   mpImageMap( NULL )
119 ,   mbInternalMove( sal_False )
120 ,   mbOwnDocument( sal_False )
121 ,   mbOwnView( sal_False )
122 ,   mbLateInit( bInitOnGetData )
123 ,   mbPageTransferable( sal_False )
124 ,   mbPageTransferablePersistent( sal_False )
125 ,   mbIsUnoObj( false )
126 ,   maUserData()
127 {
128     if( mpSourceDoc )
129         StartListening( *mpSourceDoc );
130 
131     if( pWorkView )
132         StartListening( *pWorkView );
133 
134     if( !mbLateInit )
135         CreateData();
136 }
137 
138 // -----------------------------------------------------------------------------
139 
140 SdTransferable::~SdTransferable()
141 {
142     if( mpSourceDoc )
143         EndListening( *mpSourceDoc );
144 
145     if( mpSdView )
146         EndListening( *const_cast< sd::View *>( mpSdView) );
147 
148     Application::GetSolarMutex().acquire();
149 
150     ObjectReleased();
151 
152     for( void* p = maPageBookmarks.First(); p; p = maPageBookmarks.Next() )
153         delete static_cast< String* >( p );
154 
155     if( mbOwnView )
156         delete mpSdViewIntern;
157 
158     delete mpOLEDataHelper;
159 
160     if( maDocShellRef.Is() )
161     {
162         SfxObjectShell* pObj = maDocShellRef;
163         ::sd::DrawDocShell* pDocSh = static_cast< ::sd::DrawDocShell*>(pObj);
164         pDocSh->DoClose();
165     }
166 
167     maDocShellRef.Clear();
168 
169     if( mbOwnDocument )
170         delete mpSdDrawDocumentIntern;
171 
172     delete mpGraphic;
173     delete mpBookmark;
174     delete mpImageMap;
175 
176     delete mpVDev;
177     delete mpObjDesc;
178 
179     Application::GetSolarMutex().release();
180 }
181 
182 // -----------------------------------------------------------------------------
183 
184 void SdTransferable::CreateObjectReplacement( SdrObject* pObj )
185 {
186     if( pObj )
187     {
188         delete mpOLEDataHelper, mpOLEDataHelper = NULL;
189         delete mpGraphic, mpGraphic = NULL;
190         delete mpBookmark, mpBookmark = NULL;
191         delete mpImageMap, mpImageMap = NULL;
192 
193         if( pObj->ISA( SdrOle2Obj ) )
194         {
195             try
196             {
197                 uno::Reference < embed::XEmbeddedObject > xObj = static_cast< SdrOle2Obj* >( pObj )->GetObjRef();
198                 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
199                 if( xObj.is() && xPersist.is() && xPersist->hasEntry() )
200                 {
201                     mpOLEDataHelper = new TransferableDataHelper( new SvEmbedTransferHelper( xObj, static_cast< SdrOle2Obj* >( pObj )->GetGraphic(), static_cast< SdrOle2Obj* >( pObj )->GetAspect() ) );
202 
203                     // TODO/LATER: the standalone handling of the graphic should not be used any more in future
204                     // The EmbedDataHelper should bring the graphic in future
205                     Graphic* pObjGr = static_cast< SdrOle2Obj* >( pObj )->GetGraphic();
206                     if ( pObjGr )
207                         mpGraphic = new Graphic( *pObjGr );
208                 }
209             }
210             catch( uno::Exception& )
211             {}
212         }
213         else if( pObj->ISA( SdrGrafObj ) && (mpSourceDoc && !mpSourceDoc->GetAnimationInfo( pObj )) )
214         {
215             mpGraphic = new Graphic( static_cast< SdrGrafObj* >( pObj )->GetTransformedGraphic() );
216         }
217         else if( pObj->IsUnoObj() && FmFormInventor == pObj->GetObjInventor() && ( pObj->GetObjIdentifier() == (sal_uInt16) OBJ_FM_BUTTON ) )
218         {
219             SdrUnoObj* pUnoCtrl = static_cast< SdrUnoObj* >( pObj );
220 
221             if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor())
222             {
223                 Reference< ::com::sun::star::awt::XControlModel > xControlModel( pUnoCtrl->GetUnoControlModel() );
224 
225                 if( !xControlModel.is() )
226                     return;
227 
228                 Reference< ::com::sun::star::beans::XPropertySet > xPropSet( xControlModel, UNO_QUERY );
229 
230                 if( !xPropSet.is() )
231                     return;
232 
233                 ::com::sun::star::form::FormButtonType  eButtonType;
234                 Any                                     aTmp( xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ButtonType" ) ) ) );
235 
236                 if( aTmp >>= eButtonType )
237                 {
238                     ::rtl::OUString aLabel, aURL;
239 
240                     xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Label" ) ) ) >>= aLabel;
241                     xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("TargetURL") ) ) >>= aURL;
242 
243                     mpBookmark = new INetBookmark( String( aURL ), String( aLabel ) );
244                 }
245             }
246         }
247         else if( pObj->ISA( SdrTextObj ) )
248         {
249             const OutlinerParaObject* pPara;
250 
251             if( (pPara = static_cast< SdrTextObj* >( pObj )->GetOutlinerParaObject()) != 0 )
252             {
253                 const SvxFieldItem* pField;
254 
255                 if( (pField = pPara->GetTextObject().GetField()) != 0 )
256                 {
257                     const SvxFieldData* pData = pField->GetField();
258 
259                     if( pData && pData->ISA( SvxURLField ) )
260                     {
261                         const SvxURLField* pURL = (SvxURLField*) pData;
262 
263                         mpBookmark = new INetBookmark( pURL->GetURL(), pURL->GetRepresentation() );
264                     }
265                 }
266             }
267         }
268 
269         SdIMapInfo* pInfo = static_cast< SdDrawDocument* >( pObj->GetModel() )->GetIMapInfo( static_cast< SdrObject* >( pObj ) );
270 
271         if( pInfo )
272             mpImageMap = new ImageMap( pInfo->GetImageMap() );
273 
274         mbIsUnoObj = pObj && pObj->IsUnoObj();
275     }
276 }
277 
278 // -----------------------------------------------------------------------------
279 
280 void SdTransferable::CreateData()
281 {
282     if( mpSdDrawDocument && !mpSdViewIntern )
283     {
284         mbOwnView = sal_True;
285 
286         SdPage* pPage = mpSdDrawDocument->GetSdPage(0, PK_STANDARD);
287 
288         if( 1 == pPage->GetObjCount() )
289             CreateObjectReplacement( pPage->GetObj( 0 ) );
290 
291         mpVDev = new VirtualDevice( *Application::GetDefaultDevice() );
292         mpVDev->SetMapMode( MapMode( mpSdDrawDocumentIntern->GetScaleUnit(), Point(), mpSdDrawDocumentIntern->GetScaleFraction(), mpSdDrawDocumentIntern->GetScaleFraction() ) );
293         mpSdViewIntern = new ::sd::View( mpSdDrawDocumentIntern, mpVDev );
294         mpSdViewIntern->EndListening(*mpSdDrawDocumentIntern );
295         mpSdViewIntern->hideMarkHandles();
296         SdrPageView* pPageView = mpSdViewIntern->ShowSdrPage(pPage);
297         ((SdrMarkView*)mpSdViewIntern)->MarkAllObj(pPageView);
298     }
299     else if( mpSdView && !mpSdDrawDocumentIntern )
300     {
301         const SdrMarkList& rMarkList = mpSdView->GetMarkedObjectList();
302 
303         if( rMarkList.GetMarkCount() == 1 )
304             CreateObjectReplacement( rMarkList.GetMark( 0 )->GetMarkedSdrObj() );
305 
306         if( mpSourceDoc )
307             mpSourceDoc->CreatingDataObj(this);
308         mpSdDrawDocumentIntern = (SdDrawDocument*) mpSdView->GetAllMarkedModel();
309         if( mpSourceDoc )
310             mpSourceDoc->CreatingDataObj(0);
311 
312         if( !maDocShellRef.Is() && mpSdDrawDocumentIntern->GetDocSh() )
313             maDocShellRef = mpSdDrawDocumentIntern->GetDocSh();
314 
315         if( !maDocShellRef.Is() )
316         {
317             DBG_ERROR( "SdTransferable::CreateData(), failed to create a model with persist, clipboard operation will fail for OLE objects!" );
318             mbOwnDocument = sal_True;
319         }
320 
321         // Groesse der Source-Seite uebernehmen
322         SdrPageView*        pPgView = mpSdView->GetSdrPageView();
323         SdPage*             pOldPage = (SdPage*) pPgView->GetPage();
324         SdrModel*           pOldModel = mpSdView->GetModel();
325         SdStyleSheetPool*   pOldStylePool = (SdStyleSheetPool*) pOldModel->GetStyleSheetPool();
326         SdStyleSheetPool*   pNewStylePool = (SdStyleSheetPool*) mpSdDrawDocumentIntern->GetStyleSheetPool();
327         SdPage*             pPage = mpSdDrawDocumentIntern->GetSdPage( 0, PK_STANDARD );
328         String              aOldLayoutName( pOldPage->GetLayoutName() );
329 
330         pPage->SetSize( pOldPage->GetSize() );
331         pPage->SetLayoutName( aOldLayoutName );
332         pNewStylePool->CopyGraphicSheets( *pOldStylePool );
333         pNewStylePool->CopyCellSheets( *pOldStylePool );
334         pNewStylePool->CopyTableStyles( *pOldStylePool );
335         aOldLayoutName.Erase( aOldLayoutName.SearchAscii( SD_LT_SEPARATOR ) );
336         SdStyleSheetVector aCreatedSheets;
337         pNewStylePool->CopyLayoutSheets( aOldLayoutName, *pOldStylePool, aCreatedSheets );
338     }
339 
340     // set VisArea and adjust objects if neccessary
341     if( maVisArea.IsEmpty() &&
342         mpSdDrawDocumentIntern && mpSdViewIntern &&
343         mpSdDrawDocumentIntern->GetPageCount() )
344     {
345         SdPage* pPage = mpSdDrawDocumentIntern->GetSdPage( 0, PK_STANDARD );
346 
347         if( 1 == mpSdDrawDocumentIntern->GetPageCount() )
348         {
349             // #112978# need to use GetAllMarkedBoundRect instead of GetAllMarkedRect to get
350             // fat lines correctly
351             Point   aOrigin( ( maVisArea = mpSdViewIntern->GetAllMarkedBoundRect() ).TopLeft() );
352             Size    aVector( -aOrigin.X(), -aOrigin.Y() );
353 
354             for( sal_uLong nObj = 0, nObjCount = pPage->GetObjCount(); nObj < nObjCount; nObj++ )
355             {
356                 SdrObject* pObj = pPage->GetObj( nObj );
357                 pObj->NbcMove( aVector );
358             }
359         }
360         else
361             maVisArea.SetSize( pPage->GetSize() );
362 
363         // Die Ausgabe soll am Nullpunkt erfolgen
364         maVisArea.SetPos( Point() );
365     }
366 }
367 
368 // -----------------------------------------------------------------------------
369 
370 sal_Bool lcl_HasOnlyControls( SdrModel* pModel )
371 {
372     sal_Bool bOnlyControls = sal_False;         // default if there are no objects
373 
374     if ( pModel )
375     {
376         SdrPage* pPage = pModel->GetPage(0);
377         if (pPage)
378         {
379             SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
380             SdrObject* pObj = aIter.Next();
381             if ( pObj )
382             {
383                 bOnlyControls = sal_True;   // only set if there are any objects at all
384                 while ( pObj )
385                 {
386                     if (!pObj->ISA(SdrUnoObj))
387                     {
388                         bOnlyControls = sal_False;
389                         break;
390                     }
391                     pObj = aIter.Next();
392                 }
393             }
394         }
395     }
396 
397     return bOnlyControls;
398 }
399 
400 // -----------------------------------------------------------------------------
401 
402 bool lcl_HasOnlyOneTable( SdrModel* pModel )
403 {
404     if ( pModel )
405     {
406         SdrPage* pPage = pModel->GetPage(0);
407         if (pPage && pPage->GetObjCount() == 1 )
408         {
409             if( dynamic_cast< sdr::table::SdrTableObj* >( pPage->GetObj(0) ) != 0 )
410                 return true;
411         }
412     }
413     return false;
414 }
415 
416 // -----------------------------------------------------------------------------
417 
418 void SdTransferable::AddSupportedFormats()
419 {
420     if( !mbPageTransferable || mbPageTransferablePersistent )
421     {
422         if( !mbLateInit )
423             CreateData();
424 
425         if( mpObjDesc )
426             AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
427 
428         if( mpOLEDataHelper )
429         {
430             AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
431 
432             DataFlavorExVector              aVector( mpOLEDataHelper->GetDataFlavorExVector() );
433             DataFlavorExVector::iterator    aIter( aVector.begin() ), aEnd( aVector.end() );
434 
435             while( aIter != aEnd )
436                 AddFormat( *aIter++ );
437         }
438         else if( mpGraphic )
439         {
440             // #i25616#
441             AddFormat( SOT_FORMATSTR_ID_DRAWING );
442 
443             AddFormat( SOT_FORMATSTR_ID_SVXB );
444 
445             if( mpGraphic->GetType() == GRAPHIC_BITMAP )
446             {
447                 AddFormat( SOT_FORMAT_BITMAP );
448                 AddFormat( SOT_FORMAT_GDIMETAFILE );
449             }
450             else
451             {
452                 AddFormat( SOT_FORMAT_GDIMETAFILE );
453                 AddFormat( SOT_FORMAT_BITMAP );
454             }
455         }
456         else if( mpBookmark )
457         {
458             AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK );
459             AddFormat( FORMAT_STRING );
460         }
461         else
462         {
463             AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
464             AddFormat( SOT_FORMATSTR_ID_DRAWING );
465             if( !mpSdDrawDocument || !lcl_HasOnlyControls( mpSdDrawDocument ) )
466             {
467                 AddFormat( SOT_FORMAT_GDIMETAFILE );
468                 AddFormat( SOT_FORMAT_BITMAP );
469             }
470 
471             if( lcl_HasOnlyOneTable( mpSdDrawDocument ) )
472                 AddFormat( SOT_FORMAT_RTF );
473         }
474 
475         if( mpImageMap )
476             AddFormat( SOT_FORMATSTR_ID_SVIM );
477     }
478 }
479 
480 // -----------------------------------------------------------------------------
481 
482 sal_Bool SdTransferable::GetData( const DataFlavor& rFlavor )
483 {
484     if (SD_MOD()==NULL)
485         return sal_False;
486 
487     sal_uInt32  nFormat = SotExchange::GetFormat( rFlavor );
488     sal_Bool    bOK = sal_False;
489 
490     CreateData();
491 
492     if( nFormat == SOT_FORMAT_RTF && lcl_HasOnlyOneTable( mpSdDrawDocument ) )
493     {
494         bOK = SetTableRTF( mpSdDrawDocument, rFlavor );
495     }
496     else if( mpOLEDataHelper && mpOLEDataHelper->HasFormat( rFlavor ) )
497     {
498         sal_uLong nOldSwapMode = 0;
499 
500         if( mpSdDrawDocumentIntern )
501         {
502             nOldSwapMode = mpSdDrawDocumentIntern->GetSwapGraphicsMode();
503             mpSdDrawDocumentIntern->SetSwapGraphicsMode( SDR_SWAPGRAPHICSMODE_PURGE );
504         }
505 
506         // TODO/LATER: support all the graphical formats, the embedded object scenario should not have separated handling
507         if( nFormat == FORMAT_GDIMETAFILE && mpGraphic )
508             bOK = SetGDIMetaFile( mpGraphic->GetGDIMetaFile(), rFlavor );
509         else
510             bOK = SetAny( mpOLEDataHelper->GetAny( rFlavor ), rFlavor );
511 
512         if( mpSdDrawDocumentIntern )
513             mpSdDrawDocumentIntern->SetSwapGraphicsMode( nOldSwapMode );
514     }
515     else if( HasFormat( nFormat ) )
516     {
517         if( ( nFormat == SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR || nFormat == SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) && mpObjDesc )
518         {
519             bOK = SetTransferableObjectDescriptor( *mpObjDesc, rFlavor );
520         }
521         else if( nFormat == SOT_FORMATSTR_ID_DRAWING )
522         {
523             SfxObjectShellRef aOldRef( maDocShellRef );
524 
525             maDocShellRef.Clear();
526 
527             if( mpSdViewIntern )
528             {
529                 SdDrawDocument* pInternDoc = mpSdViewIntern->GetDoc();
530                 if( pInternDoc )
531                     pInternDoc->CreatingDataObj(this);
532                 SdDrawDocument* pDoc = dynamic_cast< SdDrawDocument* >( mpSdViewIntern->GetAllMarkedModel() );
533                 if( pInternDoc )
534                     pInternDoc->CreatingDataObj(0);
535 
536                 bOK = SetObject( pDoc, SDTRANSFER_OBJECTTYPE_DRAWMODEL, rFlavor );
537 
538                 if( maDocShellRef.Is() )
539                 {
540                     maDocShellRef->DoClose();
541                 }
542                 else
543                 {
544                     delete pDoc;
545                 }
546             }
547 
548             maDocShellRef = aOldRef;
549         }
550         else if( nFormat == FORMAT_GDIMETAFILE )
551         {
552             if( mpSdViewIntern )
553                 bOK = SetGDIMetaFile( mpSdViewIntern->GetAllMarkedMetaFile( sal_True ), rFlavor );
554         }
555         else if( nFormat == FORMAT_BITMAP )
556         {
557             if( mpSdViewIntern )
558                 bOK = SetBitmap( mpSdViewIntern->GetAllMarkedBitmap( sal_True ), rFlavor );
559         }
560         else if( ( nFormat == FORMAT_STRING ) && mpBookmark )
561         {
562             bOK = SetString( mpBookmark->GetURL(), rFlavor );
563         }
564         else if( ( nFormat == SOT_FORMATSTR_ID_SVXB ) && mpGraphic )
565         {
566             bOK = SetGraphic( *mpGraphic, rFlavor );
567         }
568         else if( ( nFormat == SOT_FORMATSTR_ID_SVIM ) && mpImageMap )
569         {
570             bOK = SetImageMap( *mpImageMap, rFlavor );
571         }
572         else if( mpBookmark )
573         {
574             bOK = SetINetBookmark( *mpBookmark, rFlavor );
575         }
576         else if( nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE )
577         {
578             sal_uLong nOldSwapMode = 0;
579 
580             if( mpSdDrawDocumentIntern )
581             {
582                 nOldSwapMode = mpSdDrawDocumentIntern->GetSwapGraphicsMode();
583                 mpSdDrawDocumentIntern->SetSwapGraphicsMode( SDR_SWAPGRAPHICSMODE_PURGE );
584             }
585 
586             if( !maDocShellRef.Is() )
587             {
588                 maDocShellRef = new ::sd::DrawDocShell(
589                     mpSdDrawDocumentIntern,
590                     SFX_CREATE_MODE_EMBEDDED,
591                     sal_True,
592                     mpSdDrawDocumentIntern->GetDocumentType());
593                 mbOwnDocument = sal_False;
594                 maDocShellRef->DoInitNew( NULL );
595             }
596 
597             maDocShellRef->SetVisArea( maVisArea );
598             bOK = SetObject( &maDocShellRef, SDTRANSFER_OBJECTTYPE_DRAWOLE, rFlavor );
599 
600             if( mpSdDrawDocumentIntern )
601                 mpSdDrawDocumentIntern->SetSwapGraphicsMode( nOldSwapMode );
602         }
603     }
604 
605     return bOK;
606 }
607 
608 // -----------------------------------------------------------------------------
609 
610 /* testcode
611 #include <sfx2/docfile.hxx>
612 */
613 
614 sal_Bool SdTransferable::WriteObject( SotStorageStreamRef& rxOStm, void* pObject, sal_uInt32 nObjectType, const DataFlavor& )
615 {
616     sal_Bool bRet = sal_False;
617 
618     switch( nObjectType )
619     {
620         case( SDTRANSFER_OBJECTTYPE_DRAWMODEL ):
621         {
622             try
623             {
624                 static const sal_Bool bDontBurnInStyleSheet = ( getenv( "AVOID_BURN_IN_FOR_GALLERY_THEME" ) != NULL );
625                 SdDrawDocument* pDoc = (SdDrawDocument*) pObject;
626                 if ( !bDontBurnInStyleSheet )
627                     pDoc->BurnInStyleSheetAttributes();
628                 rxOStm->SetBufferSize( 16348 );
629 
630                 Reference< XComponent > xComponent( new SdXImpressDocument( pDoc, sal_True ) );
631                 pDoc->setUnoModel( Reference< XInterface >::query( xComponent ) );
632 
633                 {
634                     com::sun::star::uno::Reference<com::sun::star::io::XOutputStream> xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) );
635                     if( SvxDrawingLayerExport( pDoc, xDocOut, xComponent, (pDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS) ? "com.sun.star.comp.Impress.XMLClipboardExporter" : "com.sun.star.comp.DrawingLayer.XMLExporter" ) )
636                         rxOStm->Commit();
637                 }
638 
639     /* testcode
640                 {
641                     const rtl::OUString aURL( RTL_CONSTASCII_USTRINGPARAM( "file:///e:/test.xml" ) );
642                     SfxMedium aMedium( aURL, STREAM_WRITE | STREAM_TRUNC, sal_True );
643                     aMedium.IsRemote();
644                     com::sun::star::uno::Reference<com::sun::star::io::XOutputStream> xDocOut( new utl::OOutputStreamWrapper( *aMedium.GetOutStream() ) );
645                     if( SvxDrawingLayerExport( pDoc, xDocOut, xComponent, (pDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS) ? "com.sun.star.comp.Impress.XMLClipboardExporter" : "com.sun.star.comp.DrawingLayer.XMLExporter" ) )
646                         aMedium.Commit();
647                 }
648     */
649 
650                 xComponent->dispose();
651                 bRet = ( rxOStm->GetError() == ERRCODE_NONE );
652             }
653             catch( Exception& )
654             {
655                 DBG_ERROR( "sd::SdTransferable::WriteObject(), exception catched!" );
656                 bRet = sal_False;
657             }
658         }
659         break;
660 
661         case( SDTRANSFER_OBJECTTYPE_DRAWOLE ):
662         {
663             SfxObjectShell*   pEmbObj = (SfxObjectShell*) pObject;
664             ::utl::TempFile     aTempFile;
665             aTempFile.EnableKillingFile();
666 
667             try
668             {
669                 uno::Reference< embed::XStorage > xWorkStore =
670                     ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
671 
672                 // write document storage
673                 pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, sal_False );
674                 // mba: no relative ULRs for clipboard!
675                 SfxMedium aMedium( xWorkStore, String() );
676                 bRet = pEmbObj->DoSaveObjectAs( aMedium, sal_False );
677                 pEmbObj->DoSaveCompleted();
678 
679                 uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY );
680                 if ( xTransact.is() )
681                     xTransact->commit();
682 
683                 SvStream* pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), STREAM_READ );
684                 if( pSrcStm )
685                 {
686                     rxOStm->SetBufferSize( 0xff00 );
687                     *rxOStm << *pSrcStm;
688                     delete pSrcStm;
689                 }
690 
691                 bRet = sal_True;
692                 rxOStm->Commit();
693             }
694             catch ( Exception& )
695             {}
696         }
697 
698         break;
699 
700         default:
701         break;
702     }
703 
704     return bRet;
705 }
706 
707 // -----------------------------------------------------------------------------
708 
709 void SdTransferable::DragFinished( sal_Int8 nDropAction )
710 {
711     if( mpSdView )
712         ( (::sd::View*) mpSdView )->DragFinished( nDropAction );
713 }
714 
715 // -----------------------------------------------------------------------------
716 
717 void SdTransferable::ObjectReleased()
718 {
719     if( this == SD_MOD()->pTransferClip )
720         SD_MOD()->pTransferClip = NULL;
721 
722     if( this == SD_MOD()->pTransferDrag )
723         SD_MOD()->pTransferDrag = NULL;
724 
725     if( this == SD_MOD()->pTransferSelection )
726         SD_MOD()->pTransferSelection = NULL;
727 }
728 
729 // -----------------------------------------------------------------------------
730 
731 void SdTransferable::SetObjectDescriptor( const TransferableObjectDescriptor& rObjDesc )
732 {
733     delete mpObjDesc;
734     mpObjDesc = new TransferableObjectDescriptor( rObjDesc );
735     PrepareOLE( rObjDesc );
736 }
737 
738 // -----------------------------------------------------------------------------
739 
740 void SdTransferable::SetPageBookmarks( const List& rPageBookmarks, sal_Bool bPersistent )
741 {
742     if( mpSourceDoc )
743     {
744         if( mpSdViewIntern )
745             mpSdViewIntern->HideSdrPage();
746 
747         // #116168#
748         mpSdDrawDocument->ClearModel(sal_False);
749 
750         mpPageDocShell = NULL;
751 
752         for( void* p = maPageBookmarks.First(); p; p = maPageBookmarks.Next() )
753             delete static_cast< String* >( p );
754 
755         if( bPersistent )
756         {
757             mpSdDrawDocument->CreateFirstPages(mpSourceDoc);
758             mpSdDrawDocument->InsertBookmarkAsPage( const_cast< List* >( &rPageBookmarks ), NULL, sal_False, sal_True, 1, sal_True, mpSourceDoc->GetDocSh(), sal_True, sal_True, sal_False );
759         }
760         else
761         {
762             mpPageDocShell = mpSourceDoc->GetDocSh();
763 
764             for( sal_uLong i = 0; i < rPageBookmarks.Count(); i++ )
765                 maPageBookmarks.Insert( new String( *static_cast< String* >( rPageBookmarks.GetObject( i ) ) ), LIST_APPEND );
766         }
767 
768         if( mpSdViewIntern && mpSdDrawDocument )
769         {
770             SdPage* pPage = mpSdDrawDocument->GetSdPage( 0, PK_STANDARD );
771 
772             if( pPage )
773             {
774                 ( (SdrMarkView*) mpSdViewIntern )->MarkAllObj( (SdrPageView*) mpSdViewIntern->ShowSdrPage( pPage ) );
775             }
776         }
777 
778         // set flags for page transferable; if ( mbPageTransferablePersistent == sal_False ),
779         // don't offer any formats => it's just for internal puposes
780         mbPageTransferable = sal_True;
781         mbPageTransferablePersistent = bPersistent;
782     }
783 }
784 
785 // -----------------------------------------------------------------------------
786 
787 sal_Int64 SAL_CALL SdTransferable::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( ::com::sun::star::uno::RuntimeException )
788 {
789     sal_Int64 nRet;
790 
791     if( ( rId.getLength() == 16 ) &&
792         ( 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
793     {
794         nRet = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
795     }
796     else
797     {
798         nRet = 0;
799     }
800 
801     return nRet;
802 }
803 
804 
805 
806 
807 SdDrawDocument* SdTransferable::GetSourceDoc (void) const
808 {
809     return mpSourceDoc;
810 }
811 
812 
813 
814 
815 void SdTransferable::AddUserData (const ::boost::shared_ptr<UserData>& rpData)
816 {
817     maUserData.push_back(rpData);
818 }
819 
820 
821 
822 
823 void SdTransferable::RemoveUserData (const ::boost::shared_ptr<UserData>& rpData)
824 {
825     maUserData.erase(::std::find(maUserData.begin(), maUserData.end(), rpData));
826 }
827 
828 
829 
830 
831 sal_Int32 SdTransferable::GetUserDataCount (void) const
832 {
833     return maUserData.size();
834 }
835 
836 
837 
838 
839 ::boost::shared_ptr<SdTransferable::UserData> SdTransferable::GetUserData (const sal_Int32 nIndex) const
840 {
841     if (nIndex>=0 && nIndex<sal_Int32(maUserData.size()))
842         return maUserData[nIndex];
843     else
844         return ::boost::shared_ptr<UserData>();
845 }
846 
847 
848 
849 
850 // -----------------------------------------------------------------------------
851 
852 const ::com::sun::star::uno::Sequence< sal_Int8 >& SdTransferable::getUnoTunnelId()
853 {
854     static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
855 
856     if( !aSeq.getLength() )
857     {
858         static osl::Mutex   aCreateMutex;
859         osl::MutexGuard     aGuard( aCreateMutex );
860 
861         aSeq.realloc( 16 );
862         rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True );
863     }
864 
865     return aSeq;
866 }
867 
868 // -----------------------------------------------------------------------------
869 
870 SdTransferable* SdTransferable::getImplementation( const Reference< XInterface >& rxData ) throw()
871 {
872     try
873     {
874         Reference< ::com::sun::star::lang::XUnoTunnel > xUnoTunnel( rxData, UNO_QUERY_THROW );
875         return reinterpret_cast<SdTransferable*>(sal::static_int_cast<sal_uIntPtr>(xUnoTunnel->getSomething( SdTransferable::getUnoTunnelId()) ) );
876     }
877     catch( const ::com::sun::star::uno::Exception& )
878     {
879     }
880     return NULL;
881 }
882 
883 // -----------------------------------------------------------------------------
884 
885 // SfxListener
886 void SdTransferable::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
887 {
888     const SdrHint* pSdrHint = dynamic_cast< const SdrHint* >( &rHint );
889     if( pSdrHint )
890     {
891         if( HINT_MODELCLEARED == pSdrHint->GetKind() )
892         {
893             EndListening(*mpSourceDoc);
894             mpSourceDoc = 0;
895         }
896     }
897     else
898     {
899         const SfxSimpleHint* pSimpleHint = dynamic_cast< const SfxSimpleHint * >(&rHint);
900         if(pSimpleHint && (pSimpleHint->GetId() == SFX_HINT_DYING) )
901         {
902             if( &rBC == mpSourceDoc )
903                 mpSourceDoc = 0;
904             if( &rBC == mpSdViewIntern )
905                 mpSdViewIntern = 0;
906             if( &rBC == mpSdView )
907                 mpSdView = 0;
908         }
909     }
910 }
911 
912 sal_Bool SdTransferable::SetTableRTF( SdDrawDocument* pModel, const DataFlavor& rFlavor)
913 {
914     if ( pModel )
915     {
916         SdrPage* pPage = pModel->GetPage(0);
917         if (pPage && pPage->GetObjCount() == 1 )
918         {
919             sdr::table::SdrTableObj* pTableObj = dynamic_cast< sdr::table::SdrTableObj* >( pPage->GetObj(0) );
920             if( pTableObj )
921             {
922                 SvMemoryStream aMemStm( 65535, 65535 );
923                 sdr::table::SdrTableObj::ExportAsRTF( aMemStm, *pTableObj );
924                 return SetAny( Any( Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) ) ), rFlavor );
925             }
926         }
927     }
928 
929     return sal_False;
930 }
931