Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <com/sun/star/embed/XTransactedObject.hpp>
21 : #include <com/sun/star/embed/XEmbedPersist.hpp>
22 : #include <com/sun/star/embed/ElementModes.hpp>
23 : #include <com/sun/star/lang/XComponent.hpp>
24 : #include <osl/mutex.hxx>
25 : #include <unotools/ucbstreamhelper.hxx>
26 : #include <unotools/tempfile.hxx>
27 : #include <editeng/eeitem.hxx>
28 : #include <editeng/flditem.hxx>
29 : #include <svx/svdpagv.hxx>
30 : #include <sfx2/app.hxx>
31 : #include <vcl/msgbox.hxx>
32 : #include <svx/svdoole2.hxx>
33 : #include <svx/svdograf.hxx>
34 : #include <svx/svdotext.hxx>
35 : #include <editeng/outlobj.hxx>
36 : #include <sot/storage.hxx>
37 : #include <svl/itempool.hxx>
38 : #include <editeng/editobj.hxx>
39 : #include <svx/fmglob.hxx>
40 : #include <svx/svdouno.hxx>
41 : #include <sot/formats.hxx>
42 : #include <svl/urlbmk.hxx>
43 : #include <editeng/outliner.hxx>
44 :
45 : #include <com/sun/star/form/FormButtonType.hpp>
46 : #include <com/sun/star/beans/XPropertySet.hpp>
47 : #include <unotools/streamwrap.hxx>
48 :
49 : #include <svx/svdotable.hxx>
50 : #include <svx/unomodel.hxx>
51 : #include <svx/svditer.hxx>
52 : #include <sfx2/docfile.hxx>
53 : #include <comphelper/storagehelper.hxx>
54 : #include <comphelper/servicehelper.hxx>
55 : #include <svtools/embedtransfer.hxx>
56 : #include "DrawDocShell.hxx"
57 : #include "View.hxx"
58 : #include "sdpage.hxx"
59 : #include "drawview.hxx"
60 : #include "drawdoc.hxx"
61 : #include "stlpool.hxx"
62 : #include "strings.hrc"
63 : #include "sdresid.hxx"
64 : #include "imapinfo.hxx"
65 : #include "sdxfer.hxx"
66 : #include "unomodel.hxx"
67 : #include <vcl/virdev.hxx>
68 :
69 : using namespace ::com::sun::star;
70 : using namespace ::com::sun::star::lang;
71 : using namespace ::com::sun::star::uno;
72 : using namespace ::com::sun::star::io;
73 : using namespace ::com::sun::star::datatransfer;
74 : using namespace ::com::sun::star::datatransfer::clipboard;
75 :
76 : #define SDTRANSFER_OBJECTTYPE_DRAWMODEL 0x00000001
77 : #define SDTRANSFER_OBJECTTYPE_DRAWOLE 0x00000002
78 :
79 2 : SdTransferable::SdTransferable( SdDrawDocument* pSrcDoc, ::sd::View* pWorkView, bool bInitOnGetData )
80 : : mpPageDocShell( NULL )
81 : , mpOLEDataHelper( NULL )
82 : , mpObjDesc( NULL )
83 : , mpSdView( pWorkView )
84 : , mpSdViewIntern( pWorkView )
85 : , mpSdDrawDocument( NULL )
86 : , mpSdDrawDocumentIntern( NULL )
87 : , mpSourceDoc( pSrcDoc )
88 : , mpVDev( NULL )
89 : , mpBookmark( NULL )
90 : , mpGraphic( NULL )
91 : , mpImageMap( NULL )
92 : , mbInternalMove( false )
93 : , mbOwnDocument( false )
94 : , mbOwnView( false )
95 : , mbLateInit( bInitOnGetData )
96 : , mbPageTransferable( false )
97 : , mbPageTransferablePersistent( false )
98 : , mbIsUnoObj( false )
99 2 : , maUserData()
100 : {
101 2 : if( mpSourceDoc )
102 2 : StartListening( *mpSourceDoc );
103 :
104 2 : if( pWorkView )
105 2 : StartListening( *pWorkView );
106 :
107 2 : if( !mbLateInit )
108 0 : CreateData();
109 2 : }
110 :
111 6 : SdTransferable::~SdTransferable()
112 : {
113 2 : SolarMutexGuard g;
114 :
115 2 : if( mpSourceDoc )
116 2 : EndListening( *mpSourceDoc );
117 :
118 2 : if( mpSdView )
119 2 : EndListening( *const_cast< sd::View *>( mpSdView) );
120 :
121 2 : ObjectReleased();
122 :
123 2 : if( mbOwnView )
124 0 : delete mpSdViewIntern;
125 :
126 2 : delete mpOLEDataHelper;
127 :
128 2 : if( maDocShellRef.Is() )
129 : {
130 0 : SfxObjectShell* pObj = maDocShellRef;
131 0 : ::sd::DrawDocShell* pDocSh = static_cast< ::sd::DrawDocShell*>(pObj);
132 0 : pDocSh->DoClose();
133 : }
134 :
135 2 : maDocShellRef.Clear();
136 :
137 2 : if( mbOwnDocument )
138 0 : delete mpSdDrawDocumentIntern;
139 :
140 2 : delete mpGraphic;
141 2 : delete mpBookmark;
142 2 : delete mpImageMap;
143 :
144 2 : delete mpVDev;
145 2 : delete mpObjDesc;
146 :
147 : //call explicitly at end of dtor to be covered by above SolarMutex
148 2 : maUserData.clear();
149 4 : }
150 :
151 0 : void SdTransferable::CreateObjectReplacement( SdrObject* pObj )
152 : {
153 0 : if( pObj )
154 : {
155 0 : delete mpOLEDataHelper, mpOLEDataHelper = NULL;
156 0 : delete mpGraphic, mpGraphic = NULL;
157 0 : delete mpBookmark, mpBookmark = NULL;
158 0 : delete mpImageMap, mpImageMap = NULL;
159 :
160 0 : if( pObj->ISA( SdrOle2Obj ) )
161 : {
162 : try
163 : {
164 0 : uno::Reference < embed::XEmbeddedObject > xObj = static_cast< SdrOle2Obj* >( pObj )->GetObjRef();
165 0 : uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
166 0 : if( xObj.is() && xPersist.is() && xPersist->hasEntry() )
167 : {
168 0 : mpOLEDataHelper = new TransferableDataHelper( new SvEmbedTransferHelper( xObj, static_cast< SdrOle2Obj* >( pObj )->GetGraphic(), static_cast< SdrOle2Obj* >( pObj )->GetAspect() ) );
169 :
170 : // TODO/LATER: the standalone handling of the graphic should not be used any more in future
171 : // The EmbedDataHelper should bring the graphic in future
172 0 : const Graphic* pObjGr = static_cast< SdrOle2Obj* >( pObj )->GetGraphic();
173 0 : if ( pObjGr )
174 0 : mpGraphic = new Graphic( *pObjGr );
175 0 : }
176 : }
177 0 : catch( uno::Exception& )
178 : {}
179 : }
180 0 : else if( pObj->ISA( SdrGrafObj ) && (mpSourceDoc && !mpSourceDoc->GetAnimationInfo( pObj )) )
181 : {
182 0 : mpGraphic = new Graphic( static_cast< SdrGrafObj* >( pObj )->GetTransformedGraphic() );
183 : }
184 0 : else if( pObj->IsUnoObj() && FmFormInventor == pObj->GetObjInventor() && ( pObj->GetObjIdentifier() == (sal_uInt16) OBJ_FM_BUTTON ) )
185 : {
186 0 : SdrUnoObj* pUnoCtrl = static_cast< SdrUnoObj* >( pObj );
187 :
188 0 : if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor())
189 : {
190 0 : Reference< ::com::sun::star::awt::XControlModel > xControlModel( pUnoCtrl->GetUnoControlModel() );
191 :
192 0 : if( !xControlModel.is() )
193 0 : return;
194 :
195 0 : Reference< ::com::sun::star::beans::XPropertySet > xPropSet( xControlModel, UNO_QUERY );
196 :
197 0 : if( !xPropSet.is() )
198 0 : return;
199 :
200 : ::com::sun::star::form::FormButtonType eButtonType;
201 0 : Any aTmp( xPropSet->getPropertyValue( "ButtonType" ) );
202 :
203 0 : if( aTmp >>= eButtonType )
204 : {
205 0 : OUString aLabel, aURL;
206 :
207 0 : xPropSet->getPropertyValue( "Label" ) >>= aLabel;
208 0 : xPropSet->getPropertyValue( "TargetURL" ) >>= aURL;
209 :
210 0 : mpBookmark = new INetBookmark( aURL, aLabel );
211 0 : }
212 : }
213 : }
214 0 : else if( pObj->ISA( SdrTextObj ) )
215 : {
216 : const OutlinerParaObject* pPara;
217 :
218 0 : if( (pPara = static_cast< SdrTextObj* >( pObj )->GetOutlinerParaObject()) != 0 )
219 : {
220 : const SvxFieldItem* pField;
221 :
222 0 : if( (pField = pPara->GetTextObject().GetField()) != 0 )
223 : {
224 0 : const SvxFieldData* pData = pField->GetField();
225 :
226 0 : if( pData && pData->ISA( SvxURLField ) )
227 : {
228 0 : const SvxURLField* pURL = (SvxURLField*) pData;
229 :
230 : // #i63399# This special code identifies TextFrames which have just an URL
231 : // as content and directly add this to the clipboard, probably to avoid adding
232 : // an unnecessary DrawObject to the target where paste may take place. This is
233 : // wanted only for SdrObjects with no fill and no line, else it is necessary to
234 : // use the whole SdrObect. Test here for Line/FillStyle and take shortcut only
235 : // when both are unused
236 0 : if(!pObj->HasFillStyle() && !pObj->HasLineStyle())
237 : {
238 0 : mpBookmark = new INetBookmark( pURL->GetURL(), pURL->GetRepresentation() );
239 : }
240 : }
241 : }
242 : }
243 : }
244 :
245 0 : SdIMapInfo* pInfo = static_cast< SdDrawDocument* >( pObj->GetModel() )->GetIMapInfo( static_cast< SdrObject* >( pObj ) );
246 :
247 0 : if( pInfo )
248 0 : mpImageMap = new ImageMap( pInfo->GetImageMap() );
249 :
250 0 : mbIsUnoObj = pObj && pObj->IsUnoObj();
251 : }
252 : }
253 :
254 0 : void SdTransferable::CreateData()
255 : {
256 0 : if( mpSdDrawDocument && !mpSdViewIntern )
257 : {
258 0 : mbOwnView = true;
259 :
260 0 : SdPage* pPage = mpSdDrawDocument->GetSdPage(0, PK_STANDARD);
261 :
262 0 : if( 1 == pPage->GetObjCount() )
263 0 : CreateObjectReplacement( pPage->GetObj( 0 ) );
264 :
265 0 : mpVDev = new VirtualDevice( *Application::GetDefaultDevice() );
266 0 : mpVDev->SetMapMode( MapMode( mpSdDrawDocumentIntern->GetScaleUnit(), Point(), mpSdDrawDocumentIntern->GetScaleFraction(), mpSdDrawDocumentIntern->GetScaleFraction() ) );
267 0 : mpSdViewIntern = new ::sd::View( *mpSdDrawDocumentIntern, mpVDev );
268 0 : mpSdViewIntern->EndListening(*mpSdDrawDocumentIntern );
269 0 : mpSdViewIntern->hideMarkHandles();
270 0 : SdrPageView* pPageView = mpSdViewIntern->ShowSdrPage(pPage);
271 0 : ((SdrMarkView*)mpSdViewIntern)->MarkAllObj(pPageView);
272 : }
273 0 : else if( mpSdView && !mpSdDrawDocumentIntern )
274 : {
275 0 : const SdrMarkList& rMarkList = mpSdView->GetMarkedObjectList();
276 :
277 0 : if( rMarkList.GetMarkCount() == 1 )
278 0 : CreateObjectReplacement( rMarkList.GetMark( 0 )->GetMarkedSdrObj() );
279 :
280 0 : if( mpSourceDoc )
281 0 : mpSourceDoc->CreatingDataObj(this);
282 0 : mpSdDrawDocumentIntern = (SdDrawDocument*) mpSdView->GetMarkedObjModel();
283 0 : if( mpSourceDoc )
284 0 : mpSourceDoc->CreatingDataObj(0);
285 :
286 0 : if( !maDocShellRef.Is() && mpSdDrawDocumentIntern->GetDocSh() )
287 0 : maDocShellRef = mpSdDrawDocumentIntern->GetDocSh();
288 :
289 0 : if( !maDocShellRef.Is() )
290 : {
291 : OSL_FAIL( "SdTransferable::CreateData(), failed to create a model with persist, clipboard operation will fail for OLE objects!" );
292 0 : mbOwnDocument = true;
293 : }
294 :
295 : // Use dimension of source page
296 0 : SdrPageView* pPgView = mpSdView->GetSdrPageView();
297 0 : SdPage* pOldPage = (SdPage*) pPgView->GetPage();
298 0 : SdrModel* pOldModel = mpSdView->GetModel();
299 0 : SdStyleSheetPool* pOldStylePool = (SdStyleSheetPool*) pOldModel->GetStyleSheetPool();
300 0 : SdStyleSheetPool* pNewStylePool = (SdStyleSheetPool*) mpSdDrawDocumentIntern->GetStyleSheetPool();
301 0 : SdPage* pPage = mpSdDrawDocumentIntern->GetSdPage( 0, PK_STANDARD );
302 0 : OUString aOldLayoutName( pOldPage->GetLayoutName() );
303 :
304 0 : pPage->SetSize( pOldPage->GetSize() );
305 0 : pPage->SetLayoutName( aOldLayoutName );
306 0 : pNewStylePool->CopyGraphicSheets( *pOldStylePool );
307 0 : pNewStylePool->CopyCellSheets( *pOldStylePool );
308 0 : pNewStylePool->CopyTableStyles( *pOldStylePool );
309 0 : sal_Int32 nPos = aOldLayoutName.indexOf( SD_LT_SEPARATOR );
310 0 : if( nPos != -1 )
311 0 : aOldLayoutName = aOldLayoutName.copy( 0, nPos );
312 0 : SdStyleSheetVector aCreatedSheets;
313 0 : pNewStylePool->CopyLayoutSheets( aOldLayoutName, *pOldStylePool, aCreatedSheets );
314 : }
315 :
316 : // set VisArea and adjust objects if necessary
317 0 : if( maVisArea.IsEmpty() &&
318 0 : mpSdDrawDocumentIntern && mpSdViewIntern &&
319 0 : mpSdDrawDocumentIntern->GetPageCount() )
320 : {
321 0 : SdPage* pPage = mpSdDrawDocumentIntern->GetSdPage( 0, PK_STANDARD );
322 :
323 0 : if( 1 == mpSdDrawDocumentIntern->GetPageCount() )
324 : {
325 : // #112978# need to use GetAllMarkedBoundRect instead of GetAllMarkedRect to get
326 : // fat lines correctly
327 0 : Point aOrigin( ( maVisArea = mpSdViewIntern->GetAllMarkedBoundRect() ).TopLeft() );
328 0 : Size aVector( -aOrigin.X(), -aOrigin.Y() );
329 :
330 0 : for( size_t nObj = 0, nObjCount = pPage->GetObjCount(); nObj < nObjCount; ++nObj )
331 : {
332 0 : SdrObject* pObj = pPage->GetObj( nObj );
333 0 : pObj->NbcMove( aVector );
334 : }
335 : }
336 : else
337 0 : maVisArea.SetSize( pPage->GetSize() );
338 :
339 : // output is at the zero point
340 0 : maVisArea.SetPos( Point() );
341 : }
342 0 : }
343 :
344 0 : static bool lcl_HasOnlyControls( SdrModel* pModel )
345 : {
346 0 : bool bOnlyControls = false; // default if there are no objects
347 :
348 0 : if ( pModel )
349 : {
350 0 : SdrPage* pPage = pModel->GetPage(0);
351 0 : if (pPage)
352 : {
353 0 : SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
354 0 : SdrObject* pObj = aIter.Next();
355 0 : if ( pObj )
356 : {
357 0 : bOnlyControls = true; // only set if there are any objects at all
358 0 : while ( pObj )
359 : {
360 0 : if (!pObj->ISA(SdrUnoObj))
361 : {
362 0 : bOnlyControls = false;
363 0 : break;
364 : }
365 0 : pObj = aIter.Next();
366 : }
367 0 : }
368 : }
369 : }
370 :
371 0 : return bOnlyControls;
372 : }
373 :
374 0 : static bool lcl_HasOnlyOneTable( SdrModel* pModel )
375 : {
376 0 : if ( pModel )
377 : {
378 0 : SdrPage* pPage = pModel->GetPage(0);
379 0 : if (pPage && pPage->GetObjCount() == 1 )
380 : {
381 0 : if( dynamic_cast< sdr::table::SdrTableObj* >( pPage->GetObj(0) ) != 0 )
382 0 : return true;
383 : }
384 : }
385 0 : return false;
386 : }
387 :
388 0 : void SdTransferable::AddSupportedFormats()
389 : {
390 0 : if( !mbPageTransferable || mbPageTransferablePersistent )
391 : {
392 0 : if( !mbLateInit )
393 0 : CreateData();
394 :
395 0 : if( mpObjDesc )
396 0 : AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
397 :
398 0 : if( mpOLEDataHelper )
399 : {
400 0 : AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
401 :
402 0 : DataFlavorExVector aVector( mpOLEDataHelper->GetDataFlavorExVector() );
403 0 : DataFlavorExVector::iterator aIter( aVector.begin() ), aEnd( aVector.end() );
404 :
405 0 : while( aIter != aEnd )
406 0 : AddFormat( *aIter++ );
407 : }
408 0 : else if( mpGraphic )
409 : {
410 : // #i25616#
411 0 : AddFormat( SOT_FORMATSTR_ID_DRAWING );
412 :
413 0 : AddFormat( SOT_FORMATSTR_ID_SVXB );
414 :
415 0 : if( mpGraphic->GetType() == GRAPHIC_BITMAP )
416 : {
417 0 : AddFormat( SOT_FORMATSTR_ID_PNG );
418 0 : AddFormat( SOT_FORMAT_BITMAP );
419 0 : AddFormat( SOT_FORMAT_GDIMETAFILE );
420 : }
421 : else
422 : {
423 0 : AddFormat( SOT_FORMAT_GDIMETAFILE );
424 0 : AddFormat( SOT_FORMATSTR_ID_PNG );
425 0 : AddFormat( SOT_FORMAT_BITMAP );
426 : }
427 : }
428 0 : else if( mpBookmark )
429 : {
430 0 : AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK );
431 0 : AddFormat( FORMAT_STRING );
432 : }
433 : else
434 : {
435 0 : AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
436 0 : AddFormat( SOT_FORMATSTR_ID_DRAWING );
437 0 : if( !mpSdDrawDocument || !lcl_HasOnlyControls( mpSdDrawDocument ) )
438 : {
439 0 : AddFormat( SOT_FORMAT_GDIMETAFILE );
440 0 : AddFormat( SOT_FORMATSTR_ID_PNG );
441 0 : AddFormat( SOT_FORMAT_BITMAP );
442 : }
443 :
444 0 : if( lcl_HasOnlyOneTable( mpSdDrawDocument ) )
445 0 : AddFormat( SOT_FORMAT_RTF );
446 : }
447 :
448 0 : if( mpImageMap )
449 0 : AddFormat( SOT_FORMATSTR_ID_SVIM );
450 : }
451 0 : }
452 :
453 0 : bool SdTransferable::GetData( const DataFlavor& rFlavor, const OUString& rDestDoc )
454 : {
455 0 : if (SD_MOD()==NULL)
456 0 : return false;
457 :
458 0 : sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor );
459 0 : bool bOK = false;
460 :
461 0 : CreateData();
462 :
463 0 : if( nFormat == SOT_FORMAT_RTF && lcl_HasOnlyOneTable( mpSdDrawDocument ) )
464 : {
465 0 : bOK = SetTableRTF( mpSdDrawDocument, rFlavor );
466 : }
467 0 : else if( mpOLEDataHelper && mpOLEDataHelper->HasFormat( rFlavor ) )
468 : {
469 0 : sal_uLong nOldSwapMode = 0;
470 :
471 0 : if( mpSdDrawDocumentIntern )
472 : {
473 0 : nOldSwapMode = mpSdDrawDocumentIntern->GetSwapGraphicsMode();
474 0 : mpSdDrawDocumentIntern->SetSwapGraphicsMode( SDR_SWAPGRAPHICSMODE_PURGE );
475 : }
476 :
477 : // TODO/LATER: support all the graphical formats, the embedded object scenario should not have separated handling
478 0 : if( nFormat == FORMAT_GDIMETAFILE && mpGraphic )
479 0 : bOK = SetGDIMetaFile( mpGraphic->GetGDIMetaFile(), rFlavor );
480 : else
481 0 : bOK = SetAny( mpOLEDataHelper->GetAny(rFlavor, rDestDoc), rFlavor );
482 :
483 0 : if( mpSdDrawDocumentIntern )
484 0 : mpSdDrawDocumentIntern->SetSwapGraphicsMode( nOldSwapMode );
485 : }
486 0 : else if( HasFormat( nFormat ) )
487 : {
488 0 : if( ( nFormat == SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR || nFormat == SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) && mpObjDesc )
489 : {
490 0 : bOK = SetTransferableObjectDescriptor( *mpObjDesc, rFlavor );
491 : }
492 0 : else if( nFormat == SOT_FORMATSTR_ID_DRAWING )
493 : {
494 0 : SfxObjectShellRef aOldRef( maDocShellRef );
495 :
496 0 : maDocShellRef.Clear();
497 :
498 0 : if( mpSdViewIntern )
499 : {
500 0 : SdDrawDocument& rInternDoc = mpSdViewIntern->GetDoc();
501 0 : rInternDoc.CreatingDataObj(this);
502 0 : SdDrawDocument* pDoc = dynamic_cast< SdDrawDocument* >( mpSdViewIntern->GetMarkedObjModel() );
503 0 : rInternDoc.CreatingDataObj(0);
504 :
505 0 : bOK = SetObject( pDoc, SDTRANSFER_OBJECTTYPE_DRAWMODEL, rFlavor );
506 :
507 0 : if( maDocShellRef.Is() )
508 : {
509 0 : maDocShellRef->DoClose();
510 : }
511 : else
512 : {
513 0 : delete pDoc;
514 : }
515 : }
516 :
517 0 : maDocShellRef = aOldRef;
518 : }
519 0 : else if( nFormat == FORMAT_GDIMETAFILE )
520 : {
521 0 : if( mpSdViewIntern )
522 0 : bOK = SetGDIMetaFile( mpSdViewIntern->GetMarkedObjMetaFile( true ), rFlavor );
523 : }
524 0 : else if( FORMAT_BITMAP == nFormat || SOT_FORMATSTR_ID_PNG == nFormat )
525 : {
526 0 : if( mpSdViewIntern )
527 0 : bOK = SetBitmapEx( mpSdViewIntern->GetMarkedObjBitmapEx(true), rFlavor );
528 : }
529 0 : else if( ( nFormat == FORMAT_STRING ) && mpBookmark )
530 : {
531 0 : bOK = SetString( mpBookmark->GetURL(), rFlavor );
532 : }
533 0 : else if( ( nFormat == SOT_FORMATSTR_ID_SVXB ) && mpGraphic )
534 : {
535 0 : bOK = SetGraphic( *mpGraphic, rFlavor );
536 : }
537 0 : else if( ( nFormat == SOT_FORMATSTR_ID_SVIM ) && mpImageMap )
538 : {
539 0 : bOK = SetImageMap( *mpImageMap, rFlavor );
540 : }
541 0 : else if( mpBookmark )
542 : {
543 0 : bOK = SetINetBookmark( *mpBookmark, rFlavor );
544 : }
545 0 : else if( nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE )
546 : {
547 0 : sal_uLong nOldSwapMode = 0;
548 :
549 0 : if( mpSdDrawDocumentIntern )
550 : {
551 0 : nOldSwapMode = mpSdDrawDocumentIntern->GetSwapGraphicsMode();
552 0 : mpSdDrawDocumentIntern->SetSwapGraphicsMode( SDR_SWAPGRAPHICSMODE_PURGE );
553 :
554 0 : if( !maDocShellRef.Is() )
555 : {
556 0 : maDocShellRef = new ::sd::DrawDocShell(
557 : mpSdDrawDocumentIntern,
558 : SFX_CREATE_MODE_EMBEDDED,
559 : true,
560 0 : mpSdDrawDocumentIntern->GetDocumentType());
561 0 : mbOwnDocument = false;
562 0 : maDocShellRef->DoInitNew( NULL );
563 : }
564 :
565 0 : maDocShellRef->SetVisArea( maVisArea );
566 0 : bOK = SetObject( &maDocShellRef, SDTRANSFER_OBJECTTYPE_DRAWOLE, rFlavor );
567 :
568 0 : mpSdDrawDocumentIntern->SetSwapGraphicsMode( nOldSwapMode );
569 : }
570 : }
571 : }
572 :
573 0 : return bOK;
574 : }
575 :
576 0 : bool SdTransferable::WriteObject( SotStorageStreamRef& rxOStm, void* pObject, sal_uInt32 nObjectType, const DataFlavor& )
577 : {
578 0 : bool bRet = false;
579 :
580 0 : switch( nObjectType )
581 : {
582 : case( SDTRANSFER_OBJECTTYPE_DRAWMODEL ):
583 : {
584 : try
585 : {
586 0 : static const bool bDontBurnInStyleSheet = ( getenv( "AVOID_BURN_IN_FOR_GALLERY_THEME" ) != NULL );
587 0 : SdDrawDocument* pDoc = (SdDrawDocument*) pObject;
588 0 : if ( !bDontBurnInStyleSheet )
589 0 : pDoc->BurnInStyleSheetAttributes();
590 0 : rxOStm->SetBufferSize( 16348 );
591 :
592 0 : Reference< XComponent > xComponent( new SdXImpressDocument( pDoc, true ) );
593 0 : pDoc->setUnoModel( Reference< XInterface >::query( xComponent ) );
594 :
595 : {
596 0 : com::sun::star::uno::Reference<com::sun::star::io::XOutputStream> xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) );
597 0 : if( SvxDrawingLayerExport( pDoc, xDocOut, xComponent, (pDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS) ? "com.sun.star.comp.Impress.XMLClipboardExporter" : "com.sun.star.comp.DrawingLayer.XMLExporter" ) )
598 0 : rxOStm->Commit();
599 : }
600 :
601 0 : xComponent->dispose();
602 0 : bRet = ( rxOStm->GetError() == ERRCODE_NONE );
603 : }
604 0 : catch( Exception& )
605 : {
606 : OSL_FAIL( "sd::SdTransferable::WriteObject(), exception catched!" );
607 0 : bRet = false;
608 : }
609 : }
610 0 : break;
611 :
612 : case( SDTRANSFER_OBJECTTYPE_DRAWOLE ):
613 : {
614 0 : SfxObjectShell* pEmbObj = (SfxObjectShell*) pObject;
615 0 : ::utl::TempFile aTempFile;
616 0 : aTempFile.EnableKillingFile();
617 :
618 : try
619 : {
620 : uno::Reference< embed::XStorage > xWorkStore =
621 0 : ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
622 :
623 : // write document storage
624 0 : pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, false );
625 : // mba: no relative URLs for clipboard!
626 0 : SfxMedium aMedium( xWorkStore, OUString() );
627 0 : bRet = pEmbObj->DoSaveObjectAs( aMedium, false );
628 0 : pEmbObj->DoSaveCompleted();
629 :
630 0 : uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY );
631 0 : if ( xTransact.is() )
632 0 : xTransact->commit();
633 :
634 0 : SvStream* pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), STREAM_READ );
635 0 : if( pSrcStm )
636 : {
637 0 : rxOStm->SetBufferSize( 0xff00 );
638 0 : rxOStm->WriteStream( *pSrcStm );
639 0 : delete pSrcStm;
640 : }
641 :
642 0 : bRet = true;
643 0 : rxOStm->Commit();
644 : }
645 0 : catch ( Exception& )
646 0 : {}
647 : }
648 :
649 0 : break;
650 :
651 : default:
652 0 : break;
653 : }
654 :
655 0 : return bRet;
656 : }
657 :
658 0 : void SdTransferable::DragFinished( sal_Int8 nDropAction )
659 : {
660 0 : if( mpSdView )
661 0 : ( (::sd::View*) mpSdView )->DragFinished( nDropAction );
662 0 : }
663 :
664 4 : void SdTransferable::ObjectReleased()
665 : {
666 4 : if( this == SD_MOD()->pTransferClip )
667 0 : SD_MOD()->pTransferClip = NULL;
668 :
669 4 : if( this == SD_MOD()->pTransferDrag )
670 0 : SD_MOD()->pTransferDrag = NULL;
671 :
672 4 : if( this == SD_MOD()->pTransferSelection )
673 2 : SD_MOD()->pTransferSelection = NULL;
674 4 : }
675 :
676 2 : void SdTransferable::SetObjectDescriptor( const TransferableObjectDescriptor& rObjDesc )
677 : {
678 2 : delete mpObjDesc;
679 2 : mpObjDesc = new TransferableObjectDescriptor( rObjDesc );
680 2 : PrepareOLE( rObjDesc );
681 2 : }
682 :
683 0 : void SdTransferable::SetPageBookmarks( const std::vector<OUString> &rPageBookmarks, bool bPersistent )
684 : {
685 0 : if( mpSourceDoc )
686 : {
687 0 : if( mpSdViewIntern )
688 0 : mpSdViewIntern->HideSdrPage();
689 :
690 0 : mpSdDrawDocument->ClearModel(false);
691 :
692 0 : mpPageDocShell = NULL;
693 :
694 0 : maPageBookmarks.clear();
695 :
696 0 : if( bPersistent )
697 : {
698 0 : mpSdDrawDocument->CreateFirstPages(mpSourceDoc);
699 : mpSdDrawDocument->InsertBookmarkAsPage( rPageBookmarks, NULL, false, true, 1, true,
700 0 : mpSourceDoc->GetDocSh(), true, true, false );
701 : }
702 : else
703 : {
704 0 : mpPageDocShell = mpSourceDoc->GetDocSh();
705 0 : maPageBookmarks = rPageBookmarks;
706 : }
707 :
708 0 : if( mpSdViewIntern )
709 : {
710 0 : SdPage* pPage = mpSdDrawDocument->GetSdPage( 0, PK_STANDARD );
711 :
712 0 : if( pPage )
713 : {
714 0 : ( (SdrMarkView*) mpSdViewIntern )->MarkAllObj( (SdrPageView*) mpSdViewIntern->ShowSdrPage( pPage ) );
715 : }
716 : }
717 :
718 : // set flags for page transferable; if ( mbPageTransferablePersistent == sal_False ),
719 : // don't offer any formats => it's just for internal purposes
720 0 : mbPageTransferable = true;
721 0 : mbPageTransferablePersistent = bPersistent;
722 : }
723 0 : }
724 :
725 0 : sal_Int64 SAL_CALL SdTransferable::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( ::com::sun::star::uno::RuntimeException, std::exception )
726 : {
727 : sal_Int64 nRet;
728 :
729 0 : if( ( rId.getLength() == 16 ) &&
730 0 : ( 0 == memcmp( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
731 : {
732 0 : nRet = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
733 : }
734 : else
735 : {
736 0 : nRet = 0;
737 : }
738 :
739 0 : return nRet;
740 : }
741 :
742 0 : void SdTransferable::AddUserData (const ::boost::shared_ptr<UserData>& rpData)
743 : {
744 0 : maUserData.push_back(rpData);
745 0 : }
746 :
747 0 : sal_Int32 SdTransferable::GetUserDataCount (void) const
748 : {
749 0 : return maUserData.size();
750 : }
751 :
752 0 : ::boost::shared_ptr<SdTransferable::UserData> SdTransferable::GetUserData (const sal_Int32 nIndex) const
753 : {
754 0 : if (nIndex>=0 && nIndex<sal_Int32(maUserData.size()))
755 0 : return maUserData[nIndex];
756 : else
757 0 : return ::boost::shared_ptr<UserData>();
758 : }
759 :
760 : namespace
761 : {
762 : class theSdTransferableUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSdTransferableUnoTunnelId > {};
763 : }
764 :
765 0 : const ::com::sun::star::uno::Sequence< sal_Int8 >& SdTransferable::getUnoTunnelId()
766 : {
767 0 : return theSdTransferableUnoTunnelId::get().getSeq();
768 : }
769 :
770 0 : SdTransferable* SdTransferable::getImplementation( const Reference< XInterface >& rxData ) throw()
771 : {
772 : try
773 : {
774 0 : Reference< ::com::sun::star::lang::XUnoTunnel > xUnoTunnel( rxData, UNO_QUERY_THROW );
775 0 : return reinterpret_cast<SdTransferable*>(sal::static_int_cast<sal_uIntPtr>(xUnoTunnel->getSomething( SdTransferable::getUnoTunnelId()) ) );
776 : }
777 0 : catch( const ::com::sun::star::uno::Exception& )
778 : {
779 : }
780 0 : return NULL;
781 : }
782 :
783 0 : void SdTransferable::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
784 : {
785 0 : const SdrHint* pSdrHint = dynamic_cast< const SdrHint* >( &rHint );
786 0 : if( pSdrHint )
787 : {
788 0 : if( HINT_MODELCLEARED == pSdrHint->GetKind() )
789 : {
790 0 : EndListening(*mpSourceDoc);
791 0 : mpSourceDoc = 0;
792 : }
793 : }
794 : else
795 : {
796 0 : const SfxSimpleHint* pSimpleHint = dynamic_cast< const SfxSimpleHint * >(&rHint);
797 0 : if(pSimpleHint && (pSimpleHint->GetId() == SFX_HINT_DYING) )
798 : {
799 0 : if( &rBC == mpSourceDoc )
800 0 : mpSourceDoc = 0;
801 0 : if( &rBC == mpSdViewIntern )
802 0 : mpSdViewIntern = 0;
803 0 : if( &rBC == mpSdView )
804 0 : mpSdView = 0;
805 : }
806 : }
807 0 : }
808 :
809 0 : bool SdTransferable::SetTableRTF( SdDrawDocument* pModel, const DataFlavor& rFlavor)
810 : {
811 0 : if ( pModel )
812 : {
813 0 : SdrPage* pPage = pModel->GetPage(0);
814 0 : if (pPage && pPage->GetObjCount() == 1 )
815 : {
816 0 : sdr::table::SdrTableObj* pTableObj = dynamic_cast< sdr::table::SdrTableObj* >( pPage->GetObj(0) );
817 0 : if( pTableObj )
818 : {
819 0 : SvMemoryStream aMemStm( 65535, 65535 );
820 0 : sdr::table::SdrTableObj::ExportAsRTF( aMemStm, *pTableObj );
821 0 : return SetAny( Any( Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) ) ), rFlavor );
822 : }
823 : }
824 : }
825 :
826 0 : return false;
827 114 : }
828 :
829 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|