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 static_cast<SotClipboardFormatId>(0x00000001)
77 : #define SDTRANSFER_OBJECTTYPE_DRAWOLE static_cast<SotClipboardFormatId>(0x00000002)
78 :
79 6 : 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 6 : , maUserData()
100 : {
101 6 : if( mpSourceDoc )
102 6 : StartListening( *mpSourceDoc );
103 :
104 6 : if( pWorkView )
105 6 : StartListening( *pWorkView );
106 :
107 6 : if( !mbLateInit )
108 0 : CreateData();
109 6 : }
110 :
111 18 : SdTransferable::~SdTransferable()
112 : {
113 6 : SolarMutexGuard g;
114 :
115 6 : if( mpSourceDoc )
116 6 : EndListening( *mpSourceDoc );
117 :
118 6 : if( mpSdView )
119 6 : EndListening( *const_cast< sd::View *>( mpSdView) );
120 :
121 6 : ObjectReleased();
122 :
123 6 : if( mbOwnView )
124 0 : delete mpSdViewIntern;
125 :
126 6 : delete mpOLEDataHelper;
127 :
128 6 : 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 6 : maDocShellRef.Clear();
136 :
137 6 : if( mbOwnDocument )
138 0 : delete mpSdDrawDocumentIntern;
139 :
140 6 : delete mpGraphic;
141 6 : delete mpBookmark;
142 6 : delete mpImageMap;
143 :
144 6 : mpVDev.disposeAndClear();
145 6 : delete mpObjDesc;
146 :
147 : //call explicitly at end of dtor to be covered by above SolarMutex
148 6 : maUserData.clear();
149 12 : }
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 = static_cast<const 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 = VclPtr<VirtualDevice>::Create( *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 : 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 = static_cast<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 = static_cast<SdPage*>( pPgView->GetPage() );
298 0 : SdrModel* pOldModel = mpSdView->GetModel();
299 0 : SdStyleSheetPool* pOldStylePool = static_cast<SdStyleSheetPool*>( pOldModel->GetStyleSheetPool() );
300 0 : SdStyleSheetPool* pNewStylePool = static_cast<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( SotClipboardFormatId::OBJECTDESCRIPTOR );
397 :
398 0 : if( mpOLEDataHelper )
399 : {
400 0 : AddFormat( SotClipboardFormatId::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( SotClipboardFormatId::DRAWING );
412 :
413 0 : AddFormat( SotClipboardFormatId::SVXB );
414 :
415 0 : if( mpGraphic->GetType() == GRAPHIC_BITMAP )
416 : {
417 0 : AddFormat( SotClipboardFormatId::PNG );
418 0 : AddFormat( SotClipboardFormatId::BITMAP );
419 0 : AddFormat( SotClipboardFormatId::GDIMETAFILE );
420 : }
421 : else
422 : {
423 0 : AddFormat( SotClipboardFormatId::GDIMETAFILE );
424 0 : AddFormat( SotClipboardFormatId::PNG );
425 0 : AddFormat( SotClipboardFormatId::BITMAP );
426 : }
427 : }
428 0 : else if( mpBookmark )
429 : {
430 0 : AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
431 0 : AddFormat( SotClipboardFormatId::STRING );
432 : }
433 : else
434 : {
435 0 : AddFormat( SotClipboardFormatId::EMBED_SOURCE );
436 0 : AddFormat( SotClipboardFormatId::DRAWING );
437 0 : if( !mpSdDrawDocument || !lcl_HasOnlyControls( mpSdDrawDocument ) )
438 : {
439 0 : AddFormat( SotClipboardFormatId::GDIMETAFILE );
440 0 : AddFormat( SotClipboardFormatId::PNG );
441 0 : AddFormat( SotClipboardFormatId::BITMAP );
442 : }
443 :
444 0 : if( lcl_HasOnlyOneTable( mpSdDrawDocument ) )
445 0 : AddFormat( SotClipboardFormatId::RTF );
446 : }
447 :
448 0 : if( mpImageMap )
449 0 : AddFormat( SotClipboardFormatId::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 : SotClipboardFormatId nFormat = SotExchange::GetFormat( rFlavor );
459 0 : bool bOK = false;
460 :
461 0 : CreateData();
462 :
463 0 : if( nFormat == SotClipboardFormatId::RTF && lcl_HasOnlyOneTable( mpSdDrawDocument ) )
464 : {
465 0 : bOK = SetTableRTF( mpSdDrawDocument, rFlavor );
466 : }
467 0 : else if( mpOLEDataHelper && mpOLEDataHelper->HasFormat( rFlavor ) )
468 : {
469 0 : SdrSwapGraphicsMode nOldSwapMode(SdrSwapGraphicsMode::DEFAULT);
470 :
471 0 : if( mpSdDrawDocumentIntern )
472 : {
473 0 : nOldSwapMode = mpSdDrawDocumentIntern->GetSwapGraphicsMode();
474 0 : mpSdDrawDocumentIntern->SetSwapGraphicsMode( SdrSwapGraphicsMode::PURGE );
475 : }
476 :
477 : // TODO/LATER: support all the graphical formats, the embedded object scenario should not have separated handling
478 0 : if( nFormat == SotClipboardFormatId::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 == SotClipboardFormatId::LINKSRCDESCRIPTOR || nFormat == SotClipboardFormatId::OBJECTDESCRIPTOR ) && mpObjDesc )
489 : {
490 0 : bOK = SetTransferableObjectDescriptor( *mpObjDesc, rFlavor );
491 : }
492 0 : else if( nFormat == SotClipboardFormatId::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 == SotClipboardFormatId::GDIMETAFILE )
520 : {
521 0 : if (mpSdViewIntern)
522 : {
523 0 : const bool bToggleOnlineSpell = mpSdDrawDocumentIntern && mpSdDrawDocumentIntern->GetOnlineSpell();
524 0 : if (bToggleOnlineSpell)
525 0 : mpSdDrawDocumentIntern->SetOnlineSpell(false);
526 0 : bOK = SetGDIMetaFile( mpSdViewIntern->GetMarkedObjMetaFile( true ), rFlavor );
527 0 : if (bToggleOnlineSpell)
528 0 : mpSdDrawDocumentIntern->SetOnlineSpell(true);
529 : }
530 : }
531 0 : else if( SotClipboardFormatId::BITMAP == nFormat || SotClipboardFormatId::PNG == nFormat )
532 : {
533 0 : if (mpSdViewIntern)
534 : {
535 0 : const bool bToggleOnlineSpell = mpSdDrawDocumentIntern && mpSdDrawDocumentIntern->GetOnlineSpell();
536 0 : if (bToggleOnlineSpell)
537 0 : mpSdDrawDocumentIntern->SetOnlineSpell(false);
538 0 : bOK = SetBitmapEx( mpSdViewIntern->GetMarkedObjBitmapEx(true), rFlavor );
539 0 : if (bToggleOnlineSpell)
540 0 : mpSdDrawDocumentIntern->SetOnlineSpell(true);
541 0 : }
542 : }
543 0 : else if( ( nFormat == SotClipboardFormatId::STRING ) && mpBookmark )
544 : {
545 0 : bOK = SetString( mpBookmark->GetURL(), rFlavor );
546 : }
547 0 : else if( ( nFormat == SotClipboardFormatId::SVXB ) && mpGraphic )
548 : {
549 0 : bOK = SetGraphic( *mpGraphic, rFlavor );
550 : }
551 0 : else if( ( nFormat == SotClipboardFormatId::SVIM ) && mpImageMap )
552 : {
553 0 : bOK = SetImageMap( *mpImageMap, rFlavor );
554 : }
555 0 : else if( mpBookmark )
556 : {
557 0 : bOK = SetINetBookmark( *mpBookmark, rFlavor );
558 : }
559 0 : else if( nFormat == SotClipboardFormatId::EMBED_SOURCE )
560 : {
561 0 : if( mpSdDrawDocumentIntern )
562 : {
563 0 : SdrSwapGraphicsMode nOldSwapMode = mpSdDrawDocumentIntern->GetSwapGraphicsMode();
564 0 : mpSdDrawDocumentIntern->SetSwapGraphicsMode( SdrSwapGraphicsMode::PURGE );
565 :
566 0 : if( !maDocShellRef.Is() )
567 : {
568 0 : maDocShellRef = new ::sd::DrawDocShell(
569 : mpSdDrawDocumentIntern,
570 : SfxObjectCreateMode::EMBEDDED,
571 : true,
572 0 : mpSdDrawDocumentIntern->GetDocumentType());
573 0 : mbOwnDocument = false;
574 0 : maDocShellRef->DoInitNew( NULL );
575 : }
576 :
577 0 : maDocShellRef->SetVisArea( maVisArea );
578 0 : bOK = SetObject( &maDocShellRef, SDTRANSFER_OBJECTTYPE_DRAWOLE, rFlavor );
579 :
580 0 : mpSdDrawDocumentIntern->SetSwapGraphicsMode( nOldSwapMode );
581 : }
582 : }
583 : }
584 :
585 0 : return bOK;
586 : }
587 :
588 0 : bool SdTransferable::WriteObject( tools::SvRef<SotStorageStream>& rxOStm, void* pObject, SotClipboardFormatId nObjectType, const DataFlavor& )
589 : {
590 0 : bool bRet = false;
591 :
592 0 : switch( nObjectType )
593 : {
594 : case( SDTRANSFER_OBJECTTYPE_DRAWMODEL ):
595 : {
596 : try
597 : {
598 0 : static const bool bDontBurnInStyleSheet = ( getenv( "AVOID_BURN_IN_FOR_GALLERY_THEME" ) != NULL );
599 0 : SdDrawDocument* pDoc = static_cast<SdDrawDocument*>(pObject);
600 0 : if ( !bDontBurnInStyleSheet )
601 0 : pDoc->BurnInStyleSheetAttributes();
602 0 : rxOStm->SetBufferSize( 16348 );
603 :
604 0 : Reference< XComponent > xComponent( new SdXImpressDocument( pDoc, true ) );
605 0 : pDoc->setUnoModel( Reference< XInterface >::query( xComponent ) );
606 :
607 : {
608 0 : com::sun::star::uno::Reference<com::sun::star::io::XOutputStream> xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) );
609 0 : if( SvxDrawingLayerExport( pDoc, xDocOut, xComponent, (pDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS) ? "com.sun.star.comp.Impress.XMLClipboardExporter" : "com.sun.star.comp.DrawingLayer.XMLExporter" ) )
610 0 : rxOStm->Commit();
611 : }
612 :
613 0 : xComponent->dispose();
614 0 : bRet = ( rxOStm->GetError() == ERRCODE_NONE );
615 : }
616 0 : catch( Exception& )
617 : {
618 : OSL_FAIL( "sd::SdTransferable::WriteObject(), exception catched!" );
619 0 : bRet = false;
620 : }
621 : }
622 0 : break;
623 :
624 : case( SDTRANSFER_OBJECTTYPE_DRAWOLE ):
625 : {
626 0 : SfxObjectShell* pEmbObj = static_cast<SfxObjectShell*>(pObject);
627 0 : ::utl::TempFile aTempFile;
628 0 : aTempFile.EnableKillingFile();
629 :
630 : try
631 : {
632 : uno::Reference< embed::XStorage > xWorkStore =
633 0 : ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
634 :
635 : // write document storage
636 0 : pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, false );
637 : // mba: no relative URLs for clipboard!
638 0 : SfxMedium aMedium( xWorkStore, OUString() );
639 0 : bRet = pEmbObj->DoSaveObjectAs( aMedium, false );
640 0 : pEmbObj->DoSaveCompleted();
641 :
642 0 : uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY );
643 0 : if ( xTransact.is() )
644 0 : xTransact->commit();
645 :
646 0 : SvStream* pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), StreamMode::READ );
647 0 : if( pSrcStm )
648 : {
649 0 : rxOStm->SetBufferSize( 0xff00 );
650 0 : rxOStm->WriteStream( *pSrcStm );
651 0 : delete pSrcStm;
652 : }
653 :
654 0 : bRet = true;
655 0 : rxOStm->Commit();
656 : }
657 0 : catch ( Exception& )
658 0 : {}
659 : }
660 :
661 0 : break;
662 :
663 : default:
664 0 : break;
665 : }
666 :
667 0 : return bRet;
668 : }
669 :
670 0 : void SdTransferable::DragFinished( sal_Int8 nDropAction )
671 : {
672 0 : if( mpSdView )
673 0 : const_cast< ::sd::View* >(mpSdView)->DragFinished( nDropAction );
674 0 : }
675 :
676 12 : void SdTransferable::ObjectReleased()
677 : {
678 12 : if( this == SD_MOD()->pTransferClip )
679 0 : SD_MOD()->pTransferClip = NULL;
680 :
681 12 : if( this == SD_MOD()->pTransferDrag )
682 0 : SD_MOD()->pTransferDrag = NULL;
683 :
684 12 : if( this == SD_MOD()->pTransferSelection )
685 6 : SD_MOD()->pTransferSelection = NULL;
686 12 : }
687 :
688 6 : void SdTransferable::SetObjectDescriptor( const TransferableObjectDescriptor& rObjDesc )
689 : {
690 6 : delete mpObjDesc;
691 6 : mpObjDesc = new TransferableObjectDescriptor( rObjDesc );
692 6 : PrepareOLE( rObjDesc );
693 6 : }
694 :
695 0 : void SdTransferable::SetPageBookmarks( const std::vector<OUString> &rPageBookmarks, bool bPersistent )
696 : {
697 0 : if( mpSourceDoc )
698 : {
699 0 : if( mpSdViewIntern )
700 0 : mpSdViewIntern->HideSdrPage();
701 :
702 0 : mpSdDrawDocument->ClearModel(false);
703 :
704 0 : mpPageDocShell = NULL;
705 :
706 0 : maPageBookmarks.clear();
707 :
708 0 : if( bPersistent )
709 : {
710 0 : mpSdDrawDocument->CreateFirstPages(mpSourceDoc);
711 : mpSdDrawDocument->InsertBookmarkAsPage( rPageBookmarks, NULL, false, true, 1, true,
712 0 : mpSourceDoc->GetDocSh(), true, true, false );
713 : }
714 : else
715 : {
716 0 : mpPageDocShell = mpSourceDoc->GetDocSh();
717 0 : maPageBookmarks = rPageBookmarks;
718 : }
719 :
720 0 : if( mpSdViewIntern )
721 : {
722 0 : SdPage* pPage = mpSdDrawDocument->GetSdPage( 0, PK_STANDARD );
723 :
724 0 : if( pPage )
725 : {
726 0 : mpSdViewIntern->MarkAllObj( mpSdViewIntern->ShowSdrPage( pPage ) );
727 : }
728 : }
729 :
730 : // set flags for page transferable; if ( mbPageTransferablePersistent == sal_False ),
731 : // don't offer any formats => it's just for internal purposes
732 0 : mbPageTransferable = true;
733 0 : mbPageTransferablePersistent = bPersistent;
734 : }
735 0 : }
736 :
737 0 : sal_Int64 SAL_CALL SdTransferable::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( ::com::sun::star::uno::RuntimeException, std::exception )
738 : {
739 : sal_Int64 nRet;
740 :
741 0 : if( ( rId.getLength() == 16 ) &&
742 0 : ( 0 == memcmp( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
743 : {
744 0 : nRet = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
745 : }
746 : else
747 : {
748 0 : nRet = 0;
749 : }
750 :
751 0 : return nRet;
752 : }
753 :
754 0 : void SdTransferable::AddUserData (const ::boost::shared_ptr<UserData>& rpData)
755 : {
756 0 : maUserData.push_back(rpData);
757 0 : }
758 :
759 0 : sal_Int32 SdTransferable::GetUserDataCount() const
760 : {
761 0 : return maUserData.size();
762 : }
763 :
764 0 : ::boost::shared_ptr<SdTransferable::UserData> SdTransferable::GetUserData (const sal_Int32 nIndex) const
765 : {
766 0 : if (nIndex>=0 && nIndex<sal_Int32(maUserData.size()))
767 0 : return maUserData[nIndex];
768 : else
769 0 : return ::boost::shared_ptr<UserData>();
770 : }
771 :
772 : namespace
773 : {
774 : class theSdTransferableUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSdTransferableUnoTunnelId > {};
775 : }
776 :
777 0 : const ::com::sun::star::uno::Sequence< sal_Int8 >& SdTransferable::getUnoTunnelId()
778 : {
779 0 : return theSdTransferableUnoTunnelId::get().getSeq();
780 : }
781 :
782 0 : SdTransferable* SdTransferable::getImplementation( const Reference< XInterface >& rxData ) throw()
783 : {
784 : try
785 : {
786 0 : Reference< ::com::sun::star::lang::XUnoTunnel > xUnoTunnel( rxData, UNO_QUERY_THROW );
787 0 : return reinterpret_cast<SdTransferable*>(sal::static_int_cast<sal_uIntPtr>(xUnoTunnel->getSomething( SdTransferable::getUnoTunnelId()) ) );
788 : }
789 0 : catch( const ::com::sun::star::uno::Exception& )
790 : {
791 : }
792 0 : return NULL;
793 : }
794 :
795 13 : void SdTransferable::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
796 : {
797 13 : const SdrHint* pSdrHint = dynamic_cast< const SdrHint* >( &rHint );
798 13 : if( pSdrHint )
799 : {
800 10 : if( HINT_MODELCLEARED == pSdrHint->GetKind() )
801 : {
802 0 : EndListening(*mpSourceDoc);
803 0 : mpSourceDoc = 0;
804 : }
805 : }
806 : else
807 : {
808 3 : const SfxSimpleHint* pSimpleHint = dynamic_cast< const SfxSimpleHint * >(&rHint);
809 3 : if(pSimpleHint && (pSimpleHint->GetId() == SFX_HINT_DYING) )
810 : {
811 0 : if( &rBC == mpSourceDoc )
812 0 : mpSourceDoc = 0;
813 0 : if( &rBC == mpSdViewIntern )
814 0 : mpSdViewIntern = 0;
815 0 : if( &rBC == mpSdView )
816 0 : mpSdView = 0;
817 : }
818 : }
819 13 : }
820 :
821 0 : void SdTransferable::SetView(const ::sd::View* pView)
822 : {
823 0 : if (mpSdView)
824 0 : EndListening(*const_cast<sd::View*>(mpSdView));
825 0 : mpSdView = pView;
826 0 : if (mpSdView)
827 0 : StartListening(*const_cast<sd::View*>(mpSdView));
828 0 : }
829 :
830 0 : bool SdTransferable::SetTableRTF( SdDrawDocument* pModel, const DataFlavor& rFlavor)
831 : {
832 0 : if ( pModel )
833 : {
834 0 : SdrPage* pPage = pModel->GetPage(0);
835 0 : if (pPage && pPage->GetObjCount() == 1 )
836 : {
837 0 : sdr::table::SdrTableObj* pTableObj = dynamic_cast< sdr::table::SdrTableObj* >( pPage->GetObj(0) );
838 0 : if( pTableObj )
839 : {
840 0 : SvMemoryStream aMemStm( 65535, 65535 );
841 0 : sdr::table::SdrTableObj::ExportAsRTF( aMemStm, *pTableObj );
842 0 : return SetAny( Any( Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) ) ), rFlavor );
843 : }
844 : }
845 : }
846 :
847 0 : return false;
848 66 : }
849 :
850 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|