bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / ui / view / sdview3.cxx
bloba02ec4e709bd049f932b44c791ce7095f407d3da
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "View.hxx"
21 #include <com/sun/star/embed/XEmbedObjectClipboardCreator.hpp>
22 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
23 #include <com/sun/star/embed/MSOLEObjectSystemCreator.hpp>
24 #include <com/sun/star/lang/XComponent.hpp>
25 #include <sot/filelist.hxx>
26 #include <unotools/pathoptions.hxx>
27 #include <editeng/editdata.hxx>
28 #include <svl/urlbmk.hxx>
29 #include <svx/xexch.hxx>
30 #include <svx/xflclit.hxx>
31 #include <svx/xlnclit.hxx>
32 #include <svx/svdpagv.hxx>
33 #include <editeng/eeitem.hxx>
34 #include <editeng/colritem.hxx>
35 #include <sfx2/docfile.hxx>
36 #include <svx/svditer.hxx>
37 #include <svx/svdogrp.hxx>
38 #include <svx/svdoole2.hxx>
39 #include <svx/svdograf.hxx>
40 #include <svx/svdetc.hxx>
41 #include <svx/svdundo.hxx>
42 #include <sfx2/app.hxx>
43 #include <svl/itempool.hxx>
44 #include <comphelper/classids.hxx>
45 #include <svx/fmmodel.hxx>
46 #include <sot/formats.hxx>
47 #include <editeng/outliner.hxx>
48 #include <editeng/editeng.hxx>
49 #include <svx/obj3d.hxx>
50 #include <svx/e3dundo.hxx>
51 #include <svx/unomodel.hxx>
52 #include <unotools/streamwrap.hxx>
53 #include <vcl/metaact.hxx>
54 #include <svx/svxids.hrc>
55 #include <toolkit/helper/vclunohelper.hxx>
56 #include <svtools/embedhlp.hxx>
57 #include "DrawDocShell.hxx"
58 #include "fupoor.hxx"
59 #include "tablefunction.hxx"
60 #include "Window.hxx"
61 #include "sdxfer.hxx"
62 #include "sdpage.hxx"
63 #include "DrawViewShell.hxx"
64 #include "drawdoc.hxx"
65 #include "sdresid.hxx"
66 #include "strings.hrc"
67 #include "imapinfo.hxx"
68 #include "SlideSorterViewShell.hxx"
69 #include "strmname.h"
70 #include "unomodel.hxx"
71 #include "ViewClipboard.hxx"
72 #include <sfx2/ipclient.hxx>
73 #include <comphelper/storagehelper.hxx>
74 #include <comphelper/processfactory.hxx>
75 #include <tools/stream.hxx>
76 #include <vcl/cvtgrf.hxx>
77 #include <svx/sdrhittesthelper.hxx>
78 #include <svx/xbtmpit.hxx>
79 #include <boost/scoped_ptr.hpp>
81 // - Namespaces -
83 using namespace ::com::sun::star;
84 using namespace ::com::sun::star::lang;
85 using namespace ::com::sun::star::uno;
86 using namespace ::com::sun::star::io;
87 using namespace ::com::sun::star::datatransfer;
88 using namespace ::com::sun::star::datatransfer::clipboard;
90 namespace sd {
92 #define CHECK_FORMAT_TRANS( _def_Type ) ( ( nFormat == (_def_Type) || nFormat == SotClipboardFormatId::NONE ) && aDataHelper.HasFormat( _def_Type ) )
94 /*************************************************************************
96 |* Paste
98 \************************************************************************/
100 struct ImpRememberOrigAndClone
102 SdrObject* pOrig;
103 SdrObject* pClone;
106 SdrObject* ImpGetClone(std::vector<ImpRememberOrigAndClone*>& aConnectorContainer, SdrObject* pConnObj)
108 for(sal_uInt32 a(0); a < aConnectorContainer.size(); a++)
110 if(pConnObj == aConnectorContainer[a]->pOrig)
111 return aConnectorContainer[a]->pClone;
113 return 0L;
116 // restrict movement to WorkArea
117 void ImpCheckInsertPos(Point& rPos, const Size& rSize, const Rectangle& rWorkArea)
119 if(!rWorkArea.IsEmpty())
121 Rectangle aMarkRect(Point(rPos.X() - (rSize.Width() / 2), rPos.Y() - (rSize.Height() / 2)), rSize);
123 if(!aMarkRect.IsInside(rWorkArea))
125 if(aMarkRect.Left() < rWorkArea.Left())
127 rPos.X() += rWorkArea.Left() - aMarkRect.Left();
130 if(aMarkRect.Right() > rWorkArea.Right())
132 rPos.X() -= aMarkRect.Right() - rWorkArea.Right();
135 if(aMarkRect.Top() < rWorkArea.Top())
137 rPos.Y() += rWorkArea.Top() - aMarkRect.Top();
140 if(aMarkRect.Bottom() > rWorkArea.Bottom())
142 rPos.Y() -= aMarkRect.Bottom() - rWorkArea.Bottom();
148 bool View::InsertMetaFile( TransferableDataHelper& rDataHelper, const Point& rPos, ImageMap* pImageMap, bool bOptimize )
150 GDIMetaFile aMtf;
152 if( !rDataHelper.GetGDIMetaFile( SotClipboardFormatId::GDIMETAFILE, aMtf ) )
153 return false;
155 bool bVector = false;
156 Graphic aGraphic;
158 // check if metafile only contains a pixel image, if so insert a bitmap instead
159 if( bOptimize )
161 MetaAction* pAction = aMtf.FirstAction();
162 while( pAction && !bVector )
164 switch( pAction->GetType() )
166 case MetaActionType::POINT:
167 case MetaActionType::LINE:
168 case MetaActionType::RECT:
169 case MetaActionType::ROUNDRECT:
170 case MetaActionType::ELLIPSE:
171 case MetaActionType::ARC:
172 case MetaActionType::PIE:
173 case MetaActionType::CHORD:
174 case MetaActionType::POLYLINE:
175 case MetaActionType::POLYGON:
176 case MetaActionType::POLYPOLYGON:
177 case MetaActionType::TEXT:
178 case MetaActionType::TEXTARRAY:
179 case MetaActionType::STRETCHTEXT:
180 case MetaActionType::TEXTRECT:
181 case MetaActionType::GRADIENT:
182 case MetaActionType::HATCH:
183 case MetaActionType::WALLPAPER:
184 case MetaActionType::EPS:
185 case MetaActionType::TEXTLINE:
186 case MetaActionType::FLOATTRANSPARENT:
187 case MetaActionType::GRADIENTEX:
188 case MetaActionType::BMPSCALEPART:
189 case MetaActionType::BMPEXSCALEPART:
190 bVector = true;
191 break;
192 case MetaActionType::BMP:
193 case MetaActionType::BMPSCALE:
194 case MetaActionType::BMPEX:
195 case MetaActionType::BMPEXSCALE:
196 if( aGraphic.GetType() != GRAPHIC_NONE )
198 bVector = true;
200 else switch( pAction->GetType() )
202 case MetaActionType::BMP:
204 MetaBmpAction* pBmpAction = dynamic_cast< MetaBmpAction* >( pAction );
205 if( pBmpAction )
206 aGraphic = Graphic( pBmpAction->GetBitmap() );
208 break;
209 case MetaActionType::BMPSCALE:
211 MetaBmpScaleAction* pBmpScaleAction = dynamic_cast< MetaBmpScaleAction* >( pAction );
212 if( pBmpScaleAction )
213 aGraphic = Graphic( pBmpScaleAction->GetBitmap() );
215 break;
216 case MetaActionType::BMPEX:
218 MetaBmpExAction* pBmpExAction = dynamic_cast< MetaBmpExAction* >( pAction );
219 if( pBmpExAction )
220 aGraphic = Graphic( pBmpExAction->GetBitmapEx() );
222 break;
223 case MetaActionType::BMPEXSCALE:
225 MetaBmpExScaleAction* pBmpExScaleAction = dynamic_cast< MetaBmpExScaleAction* >( pAction );
226 if( pBmpExScaleAction )
227 aGraphic = Graphic( pBmpExScaleAction->GetBitmapEx() );
229 break;
230 default: break;
232 default: break;
235 pAction = aMtf.NextAction();
239 // it is not a vector metafile but it also has no graphic?
240 if( !bVector && (aGraphic.GetType() == GRAPHIC_NONE) )
241 bVector = true;
243 // restrict movement to WorkArea
244 Point aInsertPos( rPos );
245 Size aImageSize;
246 aImageSize = bVector ? aMtf.GetPrefSize() : aGraphic.GetSizePixel();
247 ImpCheckInsertPos(aInsertPos, aImageSize, GetWorkArea());
249 if( bVector )
250 aGraphic = Graphic( aMtf );
252 aGraphic.SetPrefMapMode( aMtf.GetPrefMapMode() );
253 aGraphic.SetPrefSize( aMtf.GetPrefSize() );
254 InsertGraphic( aGraphic, mnAction, aInsertPos, NULL, pImageMap );
256 return true;
259 bool View::InsertData( const TransferableDataHelper& rDataHelper,
260 const Point& rPos, sal_Int8& rDnDAction, bool bDrag,
261 SotClipboardFormatId nFormat, sal_uInt16 nPage, sal_uInt16 nLayer )
263 maDropPos = rPos;
264 mnAction = rDnDAction;
265 mbIsDropAllowed = false;
267 TransferableDataHelper aDataHelper( rDataHelper );
268 SdrObject* pPickObj = NULL;
269 SdPage* pPage = NULL;
270 boost::scoped_ptr<ImageMap> pImageMap;
271 bool bReturn = false;
272 bool bLink = ( ( mnAction & DND_ACTION_LINK ) != 0 );
273 bool bCopy = ( ( ( mnAction & DND_ACTION_COPY ) != 0 ) || bLink );
274 SdrInsertFlags nPasteOptions = SdrInsertFlags::SETDEFLAYER;
276 if (mpViewSh != NULL)
278 OSL_ASSERT (mpViewSh->GetViewShell()!=NULL);
279 SfxInPlaceClient* pIpClient = mpViewSh->GetViewShell()->GetIPClient();
280 if( mpViewSh->ISA(::sd::slidesorter::SlideSorterViewShell)
281 || (pIpClient!=NULL && pIpClient->IsObjectInPlaceActive()))
282 nPasteOptions |= SdrInsertFlags::DONTMARK;
285 if( bDrag )
287 SdrPageView* pPV = NULL;
288 PickObj( rPos, getHitTolLog(), pPickObj, pPV );
291 if( nPage != SDRPAGE_NOTFOUND )
292 pPage = static_cast<SdPage*>( mrDoc.GetPage( nPage ) );
294 SdTransferable* pOwnData = NULL;
295 SdTransferable* pImplementation = SdTransferable::getImplementation( aDataHelper.GetTransferable() );
297 if(pImplementation && (rDnDAction & DND_ACTION_LINK))
299 // suppress own data when it's intention is to use it as fill information
300 pImplementation = 0;
303 // try to get own transfer data
304 if( pImplementation )
306 if( SD_MOD()->pTransferClip == pImplementation )
307 pOwnData = SD_MOD()->pTransferClip;
308 else if( SD_MOD()->pTransferDrag == pImplementation )
309 pOwnData = SD_MOD()->pTransferDrag;
310 else if( SD_MOD()->pTransferSelection == pImplementation )
311 pOwnData = SD_MOD()->pTransferSelection;
314 // ImageMap?
315 if( !pOwnData && aDataHelper.HasFormat( SotClipboardFormatId::SVIM ) )
317 ::tools::SvRef<SotStorageStream> xStm;
319 if( aDataHelper.GetSotStorageStream( SotClipboardFormatId::SVIM, xStm ) )
321 pImageMap.reset(new ImageMap);
322 // mba: clipboard always must contain absolute URLs (could be from alien source)
323 pImageMap->Read( *xStm, OUString() );
327 bool bTable = false;
328 // check special cases for pasting table formats as RTL
329 if( !bLink && (nFormat == SotClipboardFormatId::NONE || (nFormat == SotClipboardFormatId::RTF)) )
331 // if the objekt supports rtf and there is a table involved, default is to create a table
332 if( aDataHelper.HasFormat( SotClipboardFormatId::RTF ) && ! aDataHelper.HasFormat( SotClipboardFormatId::DRAWING ) )
334 ::tools::SvRef<SotStorageStream> xStm;
336 if( aDataHelper.GetSotStorageStream( SotClipboardFormatId::RTF, xStm ) )
338 xStm->Seek( 0 );
340 OString aLine;
341 while (xStm->ReadLine(aLine))
343 sal_Int32 x = aLine.indexOf( "\\trowd" );
344 if (x != -1)
346 bTable = true;
347 nFormat = SotClipboardFormatId::RTF;
348 break;
355 // Changed the whole decision tree to be dependent of bReturn as a flag that
356 // the work was done; this allows to check multiple formats and not just fail
357 // when a CHECK_FORMAT_TRANS(*format*) detected format does not work. This is
358 // e.g. necessary for SotClipboardFormatId::BITMAP
359 if( pOwnData && nFormat == SotClipboardFormatId::NONE )
361 const View* pSourceView = pOwnData->GetView();
363 if( pOwnData->GetDocShell() && pOwnData->IsPageTransferable() && ISA( View ) )
365 mpClipboard->HandlePageDrop (*pOwnData);
366 bReturn = true;
368 else if( pSourceView )
370 if( pSourceView == this )
372 // same view
373 if( nLayer != SDRLAYER_NOTFOUND )
375 // drop on layer tab bar
376 SdrLayerAdmin& rLayerAdmin = mrDoc.GetLayerAdmin();
377 SdrLayer* pLayer = rLayerAdmin.GetLayerPerID( nLayer );
378 SdrPageView* pPV = GetSdrPageView();
379 OUString aLayer = pLayer->GetName();
381 if( !pPV->IsLayerLocked( aLayer ) )
383 pOwnData->SetInternalMove( true );
384 SortMarkedObjects();
386 for( size_t nM = 0; nM < GetMarkedObjectCount(); ++nM )
388 SdrMark* pM = GetSdrMarkByIndex( nM );
389 SdrObject* pO = pM->GetMarkedSdrObj();
391 if( pO )
393 // #i11702#
394 if( IsUndoEnabled() )
396 BegUndo(SD_RESSTR(STR_MODIFYLAYER));
397 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectLayerChange(*pO, pO->GetLayer(), (SdrLayerID)nLayer));
398 EndUndo();
401 pO->SetLayer( (SdrLayerID) nLayer );
405 bReturn = true;
408 else
410 SdrPageView* pPV = GetSdrPageView();
411 bool bDropOnTabBar = true;
413 if( !pPage && pPV->GetPage()->GetPageNum() != mnDragSrcPgNum )
415 pPage = static_cast<SdPage*>( pPV->GetPage() );
416 bDropOnTabBar = false;
419 if( pPage )
421 // drop on other page
422 OUString aActiveLayer = GetActiveLayer();
424 if( !pPV->IsLayerLocked( aActiveLayer ) )
426 if( !IsPresObjSelected() )
428 SdrMarkList* pMarkList;
430 if( (mnDragSrcPgNum != SDRPAGE_NOTFOUND) && (mnDragSrcPgNum != pPV->GetPage()->GetPageNum()) )
432 pMarkList = mpDragSrcMarkList;
434 else
436 // actual mark list is used
437 pMarkList = new SdrMarkList( GetMarkedObjectList());
440 pMarkList->ForceSort();
442 // stuff to remember originals and clones
443 std::vector<ImpRememberOrigAndClone*> aConnectorContainer;
444 size_t nConnectorCount = 0;
445 Point aCurPos;
447 // calculate real position of current
448 // source objects, if necessary (#103207)
449 if( pOwnData == SD_MOD()->pTransferSelection )
451 Rectangle aCurBoundRect;
453 if( pMarkList->TakeBoundRect( pPV, aCurBoundRect ) )
454 aCurPos = aCurBoundRect.TopLeft();
455 else
456 aCurPos = pOwnData->GetStartPos();
458 else
459 aCurPos = pOwnData->GetStartPos();
461 const Size aVector( maDropPos.X() - aCurPos.X(), maDropPos.Y() - aCurPos.Y() );
463 for(size_t a = 0; a < pMarkList->GetMarkCount(); ++a)
465 SdrMark* pM = pMarkList->GetMark(a);
466 SdrObject* pObj = pM->GetMarkedSdrObj()->Clone();
468 if(pObj)
470 if(!bDropOnTabBar)
472 // do a NbcMove(...) instead of setting SnapRects here
473 pObj->NbcMove(aVector);
476 pPage->InsertObject(pObj);
478 if( IsUndoEnabled() )
480 BegUndo(SD_RESSTR(STR_UNDO_DRAGDROP));
481 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pObj));
482 EndUndo();
485 ImpRememberOrigAndClone* pRem = new ImpRememberOrigAndClone;
486 pRem->pOrig = pM->GetMarkedSdrObj();
487 pRem->pClone = pObj;
488 aConnectorContainer.push_back(pRem);
490 if(pObj->ISA(SdrEdgeObj))
491 nConnectorCount++;
495 // try to re-establish connections at clones
496 if(nConnectorCount)
498 for(size_t a = 0; a < aConnectorContainer.size(); ++a)
500 ImpRememberOrigAndClone* pRem = aConnectorContainer[a];
502 if(pRem->pClone->ISA(SdrEdgeObj))
504 SdrEdgeObj* pOrigEdge = static_cast<SdrEdgeObj*>(pRem->pOrig);
505 SdrEdgeObj* pCloneEdge = static_cast<SdrEdgeObj*>(pRem->pClone);
507 // test first connection
508 SdrObjConnection& rConn0 = pOrigEdge->GetConnection(false);
509 SdrObject* pConnObj = rConn0.GetObject();
510 if(pConnObj)
512 SdrObject* pConnClone = ImpGetClone(aConnectorContainer, pConnObj);
513 if(pConnClone)
515 // if dest obj was cloned, too, re-establish connection
516 pCloneEdge->ConnectToNode(false, pConnClone);
517 pCloneEdge->GetConnection(false).SetConnectorId(rConn0.GetConnectorId());
519 else
521 // set position of connection point of original connected object
522 const SdrGluePointList* pGlueList = pConnObj->GetGluePointList();
523 if(pGlueList)
525 sal_uInt16 nInd = pGlueList->FindGluePoint(rConn0.GetConnectorId());
527 if(SDRGLUEPOINT_NOTFOUND != nInd)
529 const SdrGluePoint& rGluePoint = (*pGlueList)[nInd];
530 Point aPosition = rGluePoint.GetAbsolutePos(*pConnObj);
531 aPosition.X() += aVector.A();
532 aPosition.Y() += aVector.B();
533 pCloneEdge->SetTailPoint(false, aPosition);
539 // test second connection
540 SdrObjConnection& rConn1 = pOrigEdge->GetConnection(true);
541 pConnObj = rConn1.GetObject();
542 if(pConnObj)
544 SdrObject* pConnClone = ImpGetClone(aConnectorContainer, pConnObj);
545 if(pConnClone)
547 // if dest obj was cloned, too, re-establish connection
548 pCloneEdge->ConnectToNode(true, pConnClone);
549 pCloneEdge->GetConnection(true).SetConnectorId(rConn1.GetConnectorId());
551 else
553 // set position of connection point of original connected object
554 const SdrGluePointList* pGlueList = pConnObj->GetGluePointList();
555 if(pGlueList)
557 sal_uInt16 nInd = pGlueList->FindGluePoint(rConn1.GetConnectorId());
559 if(SDRGLUEPOINT_NOTFOUND != nInd)
561 const SdrGluePoint& rGluePoint = (*pGlueList)[nInd];
562 Point aPosition = rGluePoint.GetAbsolutePos(*pConnObj);
563 aPosition.X() += aVector.A();
564 aPosition.Y() += aVector.B();
565 pCloneEdge->SetTailPoint(true, aPosition);
574 // cleanup remember classes
575 for(size_t a = 0; a < aConnectorContainer.size(); ++a)
576 delete aConnectorContainer[a];
578 if( pMarkList != mpDragSrcMarkList )
579 delete pMarkList;
581 bReturn = true;
583 else
585 maDropErrorIdle.Start();
586 bReturn = false;
590 else
592 pOwnData->SetInternalMove( true );
593 MoveAllMarked( Size( maDropPos.X() - pOwnData->GetStartPos().X(),
594 maDropPos.Y() - pOwnData->GetStartPos().Y() ), bCopy );
595 bReturn = true;
599 else
601 // different views
602 if( !pSourceView->IsPresObjSelected() )
604 // model is owned by from AllocModel() created DocShell
605 SdDrawDocument* pSourceDoc = static_cast<SdDrawDocument*>( pSourceView->GetModel() );
606 pSourceDoc->CreatingDataObj( pOwnData );
607 SdDrawDocument* pModel = static_cast<SdDrawDocument*>( pSourceView->GetMarkedObjModel() );
608 bReturn = Paste(*pModel, maDropPos, pPage, nPasteOptions, OUString(), OUString());
610 if( !pPage )
611 pPage = static_cast<SdPage*>( GetSdrPageView()->GetPage() );
613 OUString aLayout = pPage->GetLayoutName();
614 sal_Int32 nPos = aLayout.indexOf(SD_LT_SEPARATOR);
615 if (nPos != -1)
616 aLayout = aLayout.copy(0, nPos);
617 pPage->SetPresentationLayout( aLayout, false, false );
618 pSourceDoc->CreatingDataObj( NULL );
620 else
622 maDropErrorIdle.Start();
623 bReturn = false;
627 else
629 SdDrawDocument* pWorkModel = const_cast<SdDrawDocument*>(pOwnData->GetWorkDocument());
630 SdPage* pWorkPage = pWorkModel->GetSdPage( 0, PK_STANDARD );
632 pWorkPage->SetRectsDirty();
634 // #i120393# Clipboard data uses full object geometry range
635 const Size aSize( pWorkPage->GetAllObjBoundRect().GetSize() );
637 maDropPos.X() = pOwnData->GetStartPos().X() + ( aSize.Width() >> 1 );
638 maDropPos.Y() = pOwnData->GetStartPos().Y() + ( aSize.Height() >> 1 );
640 // delete pages, that are not of any interest for us
641 for( long i = ( pWorkModel->GetPageCount() - 1 ); i >= 0; i-- )
643 SdPage* pP = static_cast< SdPage* >( pWorkModel->GetPage( (sal_uInt16) i ) );
645 if( pP->GetPageKind() != PK_STANDARD )
646 pWorkModel->DeletePage( (sal_uInt16) i );
649 bReturn = Paste(*pWorkModel, maDropPos, pPage, nPasteOptions, OUString(), OUString());
651 if( !pPage )
652 pPage = static_cast<SdPage*>( GetSdrPageView()->GetPage() );
654 OUString aLayout = pPage->GetLayoutName();
655 sal_Int32 nPos = aLayout.indexOf(SD_LT_SEPARATOR);
656 if (nPos != -1)
657 aLayout = aLayout.copy(0, nPos);
658 pPage->SetPresentationLayout( aLayout, false, false );
662 if(!bReturn && CHECK_FORMAT_TRANS( SotClipboardFormatId::DRAWING ))
664 ::tools::SvRef<SotStorageStream> xStm;
666 if( aDataHelper.GetSotStorageStream( SotClipboardFormatId::DRAWING, xStm ) )
668 DrawDocShellRef xShell = new DrawDocShell(SfxObjectCreateMode::INTERNAL);
669 xShell->DoInitNew(0);
671 SdDrawDocument* pModel = xShell->GetDoc();
672 pModel->InsertPage(pModel->AllocPage(false));
674 Reference< XComponent > xComponent( xShell->GetModel(), UNO_QUERY );
675 xStm->Seek( 0 );
677 com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream( new utl::OInputStreamWrapper( *xStm ) );
678 bReturn = SvxDrawingLayerImport( pModel, xInputStream, xComponent, "com.sun.star.comp.Impress.XMLOasisImporter" );
680 if( pModel->GetPageCount() == 0 )
682 OSL_FAIL("empty or invalid drawing xml document on clipboard!" );
684 else
686 bool bChanged = false;
688 if( bReturn )
690 if( pModel->GetSdPage( 0, PK_STANDARD )->GetObjCount() == 1 )
692 // only one object
693 SdrObject* pObj = pModel->GetSdPage( 0, PK_STANDARD )->GetObj( 0 );
694 SdrObject* pPickObj2 = NULL;
695 SdrPageView* pPV = NULL;
696 PickObj( rPos, getHitTolLog(), pPickObj2, pPV );
698 if( ( mnAction & DND_ACTION_MOVE ) && pPickObj2 && pObj )
700 // replace object
701 SdrObject* pNewObj = pObj->Clone();
702 Rectangle aPickObjRect( pPickObj2->GetCurrentBoundRect() );
703 Size aPickObjSize( aPickObjRect.GetSize() );
704 Point aVec( aPickObjRect.TopLeft() );
705 Rectangle aObjRect( pNewObj->GetCurrentBoundRect() );
706 Size aObjSize( aObjRect.GetSize() );
708 Fraction aScaleWidth( aPickObjSize.Width(), aObjSize.Width() );
709 Fraction aScaleHeight( aPickObjSize.Height(), aObjSize.Height() );
710 pNewObj->NbcResize( aObjRect.TopLeft(), aScaleWidth, aScaleHeight );
712 aVec -= aObjRect.TopLeft();
713 pNewObj->NbcMove( Size( aVec.X(), aVec.Y() ) );
715 const bool bUndo = IsUndoEnabled();
717 if( bUndo )
718 BegUndo(SD_RESSTR(STR_UNDO_DRAGDROP));
719 pNewObj->NbcSetLayer( pPickObj->GetLayer() );
720 SdrPage* pWorkPage = GetSdrPageView()->GetPage();
721 pWorkPage->InsertObject( pNewObj );
722 if( bUndo )
724 AddUndo( mrDoc.GetSdrUndoFactory().CreateUndoNewObject( *pNewObj ) );
725 AddUndo( mrDoc.GetSdrUndoFactory().CreateUndoDeleteObject( *pPickObj2 ) );
727 pWorkPage->RemoveObject( pPickObj2->GetOrdNum() );
729 if( bUndo )
731 EndUndo();
733 else
735 SdrObject::Free(pPickObj2 );
737 bChanged = true;
738 mnAction = DND_ACTION_COPY;
740 else if( ( mnAction & DND_ACTION_LINK ) && pPickObj && pObj && !pPickObj->ISA( SdrGrafObj ) && !pPickObj->ISA( SdrOle2Obj ) )
742 SfxItemSet aSet( mrDoc.GetPool() );
744 // set new attributes to object
745 const bool bUndo = IsUndoEnabled();
746 if( bUndo )
748 BegUndo( SD_RESSTR(STR_UNDO_DRAGDROP) );
749 AddUndo( mrDoc.GetSdrUndoFactory().CreateUndoAttrObject( *pPickObj ) );
752 aSet.Put( pObj->GetMergedItemSet() );
754 /* Do not take over corner radius. There are
755 gradients (rectangles) in the gallery with corner
756 radius of 0. We should not use that on the
757 object. */
758 aSet.ClearItem( SDRATTR_ECKENRADIUS );
760 const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pObj);
762 if(pSdrGrafObj)
764 // If we have a graphic as source object, use it's graphic
765 // content as fill style
766 aSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP));
767 aSet.Put(XFillBitmapItem(&mrDoc.GetPool(), pSdrGrafObj->GetGraphic()));
770 pPickObj->SetMergedItemSetAndBroadcast( aSet );
772 if( pPickObj->ISA( E3dObject ) && pObj->ISA( E3dObject ) )
774 // handle 3D attribute in addition
775 SfxItemSet aNewSet( mrDoc.GetPool(), SID_ATTR_3D_START, SID_ATTR_3D_END, 0 );
776 SfxItemSet aOldSet( mrDoc.GetPool(), SID_ATTR_3D_START, SID_ATTR_3D_END, 0 );
778 aOldSet.Put(pPickObj->GetMergedItemSet());
779 aNewSet.Put( pObj->GetMergedItemSet() );
781 if( bUndo )
782 AddUndo( new E3dAttributesUndoAction( mrDoc, static_cast<E3dObject*>(pPickObj), aNewSet, aOldSet ) );
783 pPickObj->SetMergedItemSetAndBroadcast( aNewSet );
786 if( bUndo )
787 EndUndo();
788 bChanged = true;
793 if( !bChanged )
795 SdrPage* pWorkPage = pModel->GetSdPage( 0, PK_STANDARD );
797 pWorkPage->SetRectsDirty();
799 if( pOwnData )
801 // #i120393# Clipboard data uses full object geometry range
802 const Size aSize( pWorkPage->GetAllObjBoundRect().GetSize() );
804 maDropPos.X() = pOwnData->GetStartPos().X() + ( aSize.Width() >> 1 );
805 maDropPos.Y() = pOwnData->GetStartPos().Y() + ( aSize.Height() >> 1 );
808 bReturn = Paste(*pModel, maDropPos, pPage, nPasteOptions, OUString(), OUString());
811 xShell->DoClose();
816 if(!bReturn && CHECK_FORMAT_TRANS(SotClipboardFormatId::SBA_FIELDDATAEXCHANGE))
818 OUString aOUString;
820 if( aDataHelper.GetString( SotClipboardFormatId::SBA_FIELDDATAEXCHANGE, aOUString ) )
822 SdrObject* pObj = CreateFieldControl( aOUString );
824 if( pObj )
826 Rectangle aRect( pObj->GetLogicRect() );
827 Size aSize( aRect.GetSize() );
829 maDropPos.X() -= ( aSize.Width() >> 1 );
830 maDropPos.Y() -= ( aSize.Height() >> 1 );
832 aRect.SetPos( maDropPos );
833 pObj->SetLogicRect( aRect );
834 InsertObjectAtView( pObj, *GetSdrPageView(), SdrInsertFlags::SETDEFLAYER );
835 bReturn = true;
840 if(!bReturn &&
841 !bLink &&
842 (CHECK_FORMAT_TRANS(SotClipboardFormatId::EMBED_SOURCE) || CHECK_FORMAT_TRANS(SotClipboardFormatId::EMBEDDED_OBJ)) &&
843 aDataHelper.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR))
845 //TODO/LATER: is it possible that this format is binary?! (from old versions of SO)
846 uno::Reference < io::XInputStream > xStm;
847 TransferableObjectDescriptor aObjDesc;
849 if (aDataHelper.GetTransferableObjectDescriptor(SotClipboardFormatId::OBJECTDESCRIPTOR, aObjDesc))
851 OUString aDocShellID = SfxObjectShell::CreateShellID(mrDoc.GetDocSh());
852 xStm = aDataHelper.GetInputStream(nFormat != SotClipboardFormatId::NONE ? nFormat : SotClipboardFormatId::EMBED_SOURCE, aDocShellID);
853 if (!xStm.is())
854 xStm = aDataHelper.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ, aDocShellID);
857 if (xStm.is())
859 if( mrDoc.GetDocSh() && ( mrDoc.GetDocSh()->GetClassName() == aObjDesc.maClassName ) )
861 uno::Reference < embed::XStorage > xStore( ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm ) );
862 ::sd::DrawDocShellRef xDocShRef( new ::sd::DrawDocShell( SfxObjectCreateMode::EMBEDDED, true, mrDoc.GetDocumentType() ) );
864 // mba: BaseURL doesn't make sense for clipboard functionality
865 SfxMedium *pMedium = new SfxMedium( xStore, OUString() );
866 if( xDocShRef->DoLoad( pMedium ) )
868 SdDrawDocument* pModel = xDocShRef->GetDoc();
869 SdPage* pWorkPage = pModel->GetSdPage( 0, PK_STANDARD );
871 pWorkPage->SetRectsDirty();
873 if( pOwnData )
875 // #i120393# Clipboard data uses full object geometry range
876 const Size aSize( pWorkPage->GetAllObjBoundRect().GetSize() );
878 maDropPos.X() = pOwnData->GetStartPos().X() + ( aSize.Width() >> 1 );
879 maDropPos.Y() = pOwnData->GetStartPos().Y() + ( aSize.Height() >> 1 );
882 // delete pages, that are not of any interest for us
883 for( long i = ( pModel->GetPageCount() - 1 ); i >= 0; i-- )
885 SdPage* pP = static_cast< SdPage* >( pModel->GetPage( (sal_uInt16) i ) );
887 if( pP->GetPageKind() != PK_STANDARD )
888 pModel->DeletePage( (sal_uInt16) i );
891 bReturn = Paste(*pModel, maDropPos, pPage, nPasteOptions, OUString(), OUString());
893 if( !pPage )
894 pPage = static_cast<SdPage*>(GetSdrPageView()->GetPage());
896 OUString aLayout = pPage->GetLayoutName();
897 sal_Int32 nPos = aLayout.indexOf(SD_LT_SEPARATOR);
898 if (nPos != -1)
899 aLayout = aLayout.copy(0, nPos);
900 pPage->SetPresentationLayout( aLayout, false, false );
903 xDocShRef->DoClose();
904 xDocShRef.Clear();
907 else
909 OUString aName;
910 uno::Reference < embed::XEmbeddedObject > xObj = mpDocSh->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
911 if ( xObj.is() )
913 svt::EmbeddedObjectRef aObjRef( xObj, aObjDesc.mnViewAspect );
915 // try to get the replacement image from the clipboard
916 Graphic aGraphic;
917 SotClipboardFormatId nGrFormat = SotClipboardFormatId::NONE;
919 // insert replacement image ( if there is one ) into the object helper
920 if ( nGrFormat != SotClipboardFormatId::NONE )
922 datatransfer::DataFlavor aDataFlavor;
923 SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
924 aObjRef.SetGraphic( aGraphic, aDataFlavor.MimeType );
927 Size aSize;
928 if ( aObjDesc.mnViewAspect == embed::Aspects::MSOLE_ICON )
930 if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() )
931 aSize = aObjDesc.maSize;
932 else
934 MapMode aMapMode( MAP_100TH_MM );
935 aSize = aObjRef.GetSize( &aMapMode );
938 else
940 awt::Size aSz;
941 MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( aObjDesc.mnViewAspect ) );
942 if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() )
944 Size aTmp( OutputDevice::LogicToLogic( aObjDesc.maSize, MAP_100TH_MM, aMapUnit ) );
945 aSz.Width = aTmp.Width();
946 aSz.Height = aTmp.Height();
947 xObj->setVisualAreaSize( aObjDesc.mnViewAspect, aSz );
952 aSz = xObj->getVisualAreaSize( aObjDesc.mnViewAspect );
954 catch( embed::NoVisualAreaSizeException& )
956 // if the size still was not set the default size will be set later
959 aSize = Size( aSz.Width, aSz.Height );
961 if( !aSize.Width() || !aSize.Height() )
963 aSize.Width() = 14100;
964 aSize.Height() = 10000;
965 aSize = OutputDevice::LogicToLogic( Size(14100, 10000), MAP_100TH_MM, aMapUnit );
966 aSz.Width = aSize.Width();
967 aSz.Height = aSize.Height();
968 xObj->setVisualAreaSize( aObjDesc.mnViewAspect, aSz );
971 aSize = OutputDevice::LogicToLogic( aSize, aMapUnit, MAP_100TH_MM );
974 Size aMaxSize( mrDoc.GetMaxObjSize() );
976 maDropPos.X() -= std::min( aSize.Width(), aMaxSize.Width() ) >> 1;
977 maDropPos.Y() -= std::min( aSize.Height(), aMaxSize.Height() ) >> 1;
979 Rectangle aRect( maDropPos, aSize );
980 SdrOle2Obj* pObj = new SdrOle2Obj( aObjRef, aName, aRect );
981 SdrPageView* pPV = GetSdrPageView();
982 SdrInsertFlags nOptions = SdrInsertFlags::SETDEFLAYER;
984 if (mpViewSh!=NULL)
986 OSL_ASSERT (mpViewSh->GetViewShell()!=NULL);
987 SfxInPlaceClient* pIpClient
988 = mpViewSh->GetViewShell()->GetIPClient();
989 if (pIpClient!=NULL && pIpClient->IsObjectInPlaceActive())
990 nOptions |= SdrInsertFlags::DONTMARK;
993 InsertObjectAtView( pObj, *pPV, nOptions );
995 if( pImageMap )
996 pObj->AppendUserData( new SdIMapInfo( *pImageMap ) );
998 if (pObj->IsChart())
1000 bool bDisableDataTableDialog = false;
1001 svt::EmbeddedObjectRef::TryRunningState( xObj );
1002 uno::Reference< beans::XPropertySet > xProps( xObj->getComponent(), uno::UNO_QUERY );
1003 if ( xProps.is() &&
1004 ( xProps->getPropertyValue( "DisableDataTableDialog" ) >>= bDisableDataTableDialog ) &&
1005 bDisableDataTableDialog )
1007 xProps->setPropertyValue( "DisableDataTableDialog" , uno::makeAny( sal_False ) );
1008 xProps->setPropertyValue( "DisableComplexChartTypes" , uno::makeAny( sal_False ) );
1009 uno::Reference< util::XModifiable > xModifiable( xProps, uno::UNO_QUERY );
1010 if ( xModifiable.is() )
1012 xModifiable->setModified( sal_True );
1017 bReturn = true;
1023 if(!bReturn &&
1024 !bLink &&
1025 (CHECK_FORMAT_TRANS(SotClipboardFormatId::EMBEDDED_OBJ_OLE) || CHECK_FORMAT_TRANS(SotClipboardFormatId::EMBED_SOURCE_OLE)) &&
1026 aDataHelper.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR_OLE))
1028 // online insert ole if format is forced or no gdi metafile is available
1029 if( (nFormat != SotClipboardFormatId::NONE) || !aDataHelper.HasFormat( SotClipboardFormatId::GDIMETAFILE ) )
1031 uno::Reference < io::XInputStream > xStm;
1032 TransferableObjectDescriptor aObjDesc;
1034 if ( aDataHelper.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR_OLE, aObjDesc ) )
1036 uno::Reference < embed::XEmbeddedObject > xObj;
1037 OUString aName;
1039 xStm = aDataHelper.GetInputStream(nFormat != SotClipboardFormatId::NONE ? nFormat : SotClipboardFormatId::EMBED_SOURCE_OLE, OUString());
1040 if (!xStm.is())
1041 xStm = aDataHelper.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ_OLE, OUString());
1043 if (xStm.is())
1045 xObj = mpDocSh->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
1047 else
1051 uno::Reference< embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
1052 uno::Reference < embed::XEmbedObjectClipboardCreator > xClipboardCreator =
1053 embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() );
1055 embed::InsertedObjectInfo aInfo = xClipboardCreator->createInstanceInitFromClipboard(
1056 xTmpStor,
1057 "DummyName" ,
1058 uno::Sequence< beans::PropertyValue >() );
1060 // TODO/LATER: in future InsertedObjectInfo will be used to get container related information
1061 // for example whether the object should be an iconified one
1062 xObj = aInfo.Object;
1063 if ( xObj.is() )
1064 mpDocSh->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj, aName );
1066 catch( uno::Exception& )
1070 if ( xObj.is() )
1072 svt::EmbeddedObjectRef aObjRef( xObj, aObjDesc.mnViewAspect );
1074 // try to get the replacement image from the clipboard
1075 Graphic aGraphic;
1076 SotClipboardFormatId nGrFormat = SotClipboardFormatId::NONE;
1078 // (wg. Selection Manager bei Trustet Solaris)
1079 #ifndef SOLARIS
1080 if( aDataHelper.GetGraphic( SotClipboardFormatId::SVXB, aGraphic ) )
1081 nGrFormat = SotClipboardFormatId::SVXB;
1082 else if( aDataHelper.GetGraphic( SotClipboardFormatId::GDIMETAFILE, aGraphic ) )
1083 nGrFormat = SotClipboardFormatId::GDIMETAFILE;
1084 else if( aDataHelper.GetGraphic( SotClipboardFormatId::BITMAP, aGraphic ) )
1085 nGrFormat = SotClipboardFormatId::BITMAP;
1086 #endif
1088 // insert replacement image ( if there is one ) into the object helper
1089 if ( nGrFormat != SotClipboardFormatId::NONE )
1091 datatransfer::DataFlavor aDataFlavor;
1092 SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
1093 aObjRef.SetGraphic( aGraphic, aDataFlavor.MimeType );
1096 Size aSize;
1097 if ( aObjDesc.mnViewAspect == embed::Aspects::MSOLE_ICON )
1099 if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() )
1100 aSize = aObjDesc.maSize;
1101 else
1103 MapMode aMapMode( MAP_100TH_MM );
1104 aSize = aObjRef.GetSize( &aMapMode );
1107 else
1109 MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( aObjDesc.mnViewAspect ) );
1111 awt::Size aSz;
1112 try{
1113 aSz = xObj->getVisualAreaSize( aObjDesc.mnViewAspect );
1115 catch( embed::NoVisualAreaSizeException& )
1117 // the default size will be set later
1120 if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() )
1122 Size aTmp( OutputDevice::LogicToLogic( aObjDesc.maSize, MAP_100TH_MM, aMapUnit ) );
1123 if ( aSz.Width != aTmp.Width() || aSz.Height != aTmp.Height() )
1125 aSz.Width = aTmp.Width();
1126 aSz.Height = aTmp.Height();
1127 xObj->setVisualAreaSize( aObjDesc.mnViewAspect, aSz );
1131 aSize = Size( aSz.Width, aSz.Height );
1133 if( !aSize.Width() || !aSize.Height() )
1135 aSize = OutputDevice::LogicToLogic( Size(14100, 10000), MAP_100TH_MM, aMapUnit );
1136 aSz.Width = aSize.Width();
1137 aSz.Height = aSize.Height();
1138 xObj->setVisualAreaSize( aObjDesc.mnViewAspect, aSz );
1141 aSize = OutputDevice::LogicToLogic( aSize, aMapUnit, MAP_100TH_MM );
1144 Size aMaxSize( mrDoc.GetMaxObjSize() );
1146 maDropPos.X() -= std::min( aSize.Width(), aMaxSize.Width() ) >> 1;
1147 maDropPos.Y() -= std::min( aSize.Height(), aMaxSize.Height() ) >> 1;
1149 Rectangle aRect( maDropPos, aSize );
1150 SdrOle2Obj* pObj = new SdrOle2Obj( aObjRef, aName, aRect );
1151 SdrPageView* pPV = GetSdrPageView();
1152 SdrInsertFlags nOptions = SdrInsertFlags::SETDEFLAYER;
1154 if (mpViewSh!=NULL)
1156 OSL_ASSERT (mpViewSh->GetViewShell()!=NULL);
1157 SfxInPlaceClient* pIpClient
1158 = mpViewSh->GetViewShell()->GetIPClient();
1159 if (pIpClient!=NULL && pIpClient->IsObjectInPlaceActive())
1160 nOptions |= SdrInsertFlags::DONTMARK;
1163 InsertObjectAtView( pObj, *pPV, nOptions );
1165 if( pImageMap )
1166 pObj->AppendUserData( new SdIMapInfo( *pImageMap ) );
1168 // let the object stay in loaded state after insertion
1169 pObj->Unload();
1170 bReturn = true;
1175 if( !bReturn && aDataHelper.HasFormat( SotClipboardFormatId::GDIMETAFILE ) )
1177 // if no object was inserted, insert a picture
1178 InsertMetaFile( aDataHelper, rPos, pImageMap.get(), true );
1179 bReturn = true;
1183 if(!bReturn && (!bLink || pPickObj) && CHECK_FORMAT_TRANS(SotClipboardFormatId::SVXB))
1185 ::tools::SvRef<SotStorageStream> xStm;
1187 if( aDataHelper.GetSotStorageStream( SotClipboardFormatId::SVXB, xStm ) )
1189 Point aInsertPos( rPos );
1190 Graphic aGraphic;
1192 ReadGraphic( *xStm, aGraphic );
1194 if( pOwnData && pOwnData->GetWorkDocument() )
1196 const SdDrawDocument* pWorkModel = pOwnData->GetWorkDocument();
1197 SdrPage* pWorkPage = const_cast<SdrPage*>( ( pWorkModel->GetPageCount() > 1 ) ?
1198 pWorkModel->GetSdPage( 0, PK_STANDARD ) :
1199 pWorkModel->GetPage( 0 ) );
1201 pWorkPage->SetRectsDirty();
1203 // #i120393# Clipboard data uses full object geometry range
1204 const Size aSize( pWorkPage->GetAllObjBoundRect().GetSize() );
1206 aInsertPos.X() = pOwnData->GetStartPos().X() + ( aSize.Width() >> 1 );
1207 aInsertPos.Y() = pOwnData->GetStartPos().Y() + ( aSize.Height() >> 1 );
1210 // restrict movement to WorkArea
1211 Size aImageMapSize = OutputDevice::LogicToLogic(aGraphic.GetPrefSize(),
1212 aGraphic.GetPrefMapMode(), MapMode(MAP_100TH_MM));
1214 ImpCheckInsertPos(aInsertPos, aImageMapSize, GetWorkArea());
1216 InsertGraphic( aGraphic, mnAction, aInsertPos, NULL, pImageMap.get() );
1217 bReturn = true;
1221 if(!bReturn && (!bLink || pPickObj) && CHECK_FORMAT_TRANS(SotClipboardFormatId::GDIMETAFILE))
1223 Point aInsertPos( rPos );
1225 if( pOwnData && pOwnData->GetWorkDocument() )
1228 const SdDrawDocument* pWorkModel = pOwnData->GetWorkDocument();
1229 SdrPage* pWorkPage = const_cast<SdrPage*>( ( pWorkModel->GetPageCount() > 1 ) ?
1230 pWorkModel->GetSdPage( 0, PK_STANDARD ) :
1231 pWorkModel->GetPage( 0 ) );
1233 pWorkPage->SetRectsDirty();
1235 // #i120393# Clipboard data uses full object geometry range
1236 const Size aSize( pWorkPage->GetAllObjBoundRect().GetSize() );
1238 aInsertPos.X() = pOwnData->GetStartPos().X() + ( aSize.Width() >> 1 );
1239 aInsertPos.Y() = pOwnData->GetStartPos().Y() + ( aSize.Height() >> 1 );
1242 bReturn = InsertMetaFile( aDataHelper, aInsertPos, pImageMap.get(), nFormat == SotClipboardFormatId::NONE );
1245 if(!bReturn && (!bLink || pPickObj) && CHECK_FORMAT_TRANS(SotClipboardFormatId::BITMAP))
1247 BitmapEx aBmpEx;
1249 // get basic Bitmap data
1250 aDataHelper.GetBitmapEx(SotClipboardFormatId::BITMAP, aBmpEx);
1252 if(aBmpEx.IsEmpty())
1254 // if this did not work, try to get graphic formats and convert these to bitmap
1255 Graphic aGraphic;
1257 if(aDataHelper.GetGraphic(SotClipboardFormatId::GDIMETAFILE, aGraphic))
1259 aBmpEx = aGraphic.GetBitmapEx();
1261 else if(aDataHelper.GetGraphic(SotClipboardFormatId::SVXB, aGraphic))
1263 aBmpEx = aGraphic.GetBitmapEx();
1265 else if(aDataHelper.GetGraphic(SotClipboardFormatId::BITMAP, aGraphic))
1267 aBmpEx = aGraphic.GetBitmapEx();
1271 if(!aBmpEx.IsEmpty())
1273 Point aInsertPos( rPos );
1275 if( pOwnData && pOwnData->GetWorkDocument() )
1277 const SdDrawDocument* pWorkModel = pOwnData->GetWorkDocument();
1278 SdrPage* pWorkPage = const_cast<SdrPage*>( ( pWorkModel->GetPageCount() > 1 ) ?
1279 pWorkModel->GetSdPage( 0, PK_STANDARD ) :
1280 pWorkModel->GetPage( 0 ) );
1282 pWorkPage->SetRectsDirty();
1284 // #i120393# Clipboard data uses full object geometry range
1285 const Size aSize( pWorkPage->GetAllObjBoundRect().GetSize() );
1287 aInsertPos.X() = pOwnData->GetStartPos().X() + ( aSize.Width() >> 1 );
1288 aInsertPos.Y() = pOwnData->GetStartPos().Y() + ( aSize.Height() >> 1 );
1291 // restrict movement to WorkArea
1292 Size aImageMapSize(aBmpEx.GetPrefSize());
1293 ImpCheckInsertPos(aInsertPos, aImageMapSize, GetWorkArea());
1295 InsertGraphic( aBmpEx, mnAction, aInsertPos, NULL, pImageMap.get() );
1296 bReturn = true;
1300 if(!bReturn && pPickObj && CHECK_FORMAT_TRANS( SotClipboardFormatId::XFA ) )
1302 ::tools::SvRef<SotStorageStream> xStm;
1304 if( aDataHelper.GetSotStorageStream( SotClipboardFormatId::XFA, xStm ) )
1306 XFillExchangeData aFillData( XFillAttrSetItem( &mrDoc.GetPool() ) );
1308 ReadXFillExchangeData( *xStm, aFillData );
1310 if( IsUndoEnabled() )
1312 BegUndo( SD_RESSTR(STR_UNDO_DRAGDROP) );
1313 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoAttrObject( *pPickObj ) );
1314 EndUndo();
1317 XFillAttrSetItem* pSetItem = aFillData.GetXFillAttrSetItem();
1318 SfxItemSet rSet = pSetItem->GetItemSet();
1319 drawing::FillStyle eFill = static_cast<const XFillStyleItem&>( rSet.Get( XATTR_FILLSTYLE ) ).GetValue();
1321 if( eFill == drawing::FillStyle_SOLID || eFill == drawing::FillStyle_NONE )
1323 const XFillColorItem& rColItem = static_cast<const XFillColorItem&>( rSet.Get( XATTR_FILLCOLOR ) );
1324 Color aColor( rColItem.GetColorValue() );
1325 OUString aName( rColItem.GetName() );
1326 SfxItemSet aSet( mrDoc.GetPool() );
1327 bool bClosed = pPickObj->IsClosedObj();
1328 ::sd::Window* pWin = mpViewSh->GetActiveWindow();
1329 sal_uInt16 nHitLog = (sal_uInt16) pWin->PixelToLogic(
1330 Size(FuPoor::HITPIX, 0 ) ).Width();
1331 const long n2HitLog = nHitLog << 1;
1332 Point aHitPosR( rPos );
1333 Point aHitPosL( rPos );
1334 Point aHitPosT( rPos );
1335 Point aHitPosB( rPos );
1336 const SetOfByte* pVisiLayer = &GetSdrPageView()->GetVisibleLayers();
1338 aHitPosR.X() += n2HitLog;
1339 aHitPosL.X() -= n2HitLog;
1340 aHitPosT.Y() += n2HitLog;
1341 aHitPosB.Y() -= n2HitLog;
1343 if( bClosed &&
1344 SdrObjectPrimitiveHit(*pPickObj, aHitPosR, nHitLog, *GetSdrPageView(), pVisiLayer, false) &&
1345 SdrObjectPrimitiveHit(*pPickObj, aHitPosL, nHitLog, *GetSdrPageView(), pVisiLayer, false) &&
1346 SdrObjectPrimitiveHit(*pPickObj, aHitPosT, nHitLog, *GetSdrPageView(), pVisiLayer, false) &&
1347 SdrObjectPrimitiveHit(*pPickObj, aHitPosB, nHitLog, *GetSdrPageView(), pVisiLayer, false) )
1349 // area fill
1350 if(eFill == drawing::FillStyle_SOLID )
1351 aSet.Put(XFillColorItem(aName, aColor));
1353 aSet.Put( XFillStyleItem( eFill ) );
1355 else
1356 aSet.Put( XLineColorItem( aName, aColor ) );
1358 // add text color
1359 pPickObj->SetMergedItemSetAndBroadcast( aSet );
1361 bReturn = true;
1365 if(!bReturn && !bLink && CHECK_FORMAT_TRANS(SotClipboardFormatId::HTML))
1367 ::tools::SvRef<SotStorageStream> xStm;
1369 if( aDataHelper.GetSotStorageStream( SotClipboardFormatId::HTML, xStm ) )
1371 xStm->Seek( 0 );
1372 // mba: clipboard always must contain absolute URLs (could be from alien source)
1373 bReturn = SdrView::Paste( *xStm, OUString(), EE_FORMAT_HTML, maDropPos, pPage, nPasteOptions );
1377 if(!bReturn && !bLink && CHECK_FORMAT_TRANS(SotClipboardFormatId::EDITENGINE))
1379 ::tools::SvRef<SotStorageStream> xStm;
1381 if( aDataHelper.GetSotStorageStream( SotClipboardFormatId::EDITENGINE, xStm ) )
1383 OutlinerView* pOLV = GetTextEditOutlinerView();
1385 xStm->Seek( 0 );
1387 if( pOLV )
1389 Rectangle aRect( pOLV->GetOutputArea() );
1390 Point aPos( pOLV->GetWindow()->PixelToLogic( maDropPos ) );
1392 if( aRect.IsInside( aPos ) || ( !bDrag && IsTextEdit() ) )
1394 // mba: clipboard always must contain absolute URLs (could be from alien source)
1395 pOLV->Read( *xStm, OUString(), EE_FORMAT_BIN, false, mpDocSh->GetHeaderAttributes() );
1396 bReturn = true;
1400 if( !bReturn )
1401 // mba: clipboard always must contain absolute URLs (could be from alien source)
1402 bReturn = SdrView::Paste( *xStm, OUString(), EE_FORMAT_BIN, maDropPos, pPage, nPasteOptions );
1406 if(!bReturn && !bLink && CHECK_FORMAT_TRANS(SotClipboardFormatId::RTF))
1408 ::tools::SvRef<SotStorageStream> xStm;
1410 if( aDataHelper.GetSotStorageStream( SotClipboardFormatId::RTF, xStm ) )
1412 xStm->Seek( 0 );
1414 if( bTable )
1416 bReturn = PasteRTFTable( xStm, pPage, nPasteOptions );
1418 else
1420 OutlinerView* pOLV = GetTextEditOutlinerView();
1422 if( pOLV )
1424 Rectangle aRect( pOLV->GetOutputArea() );
1425 Point aPos( pOLV->GetWindow()->PixelToLogic( maDropPos ) );
1427 if( aRect.IsInside( aPos ) || ( !bDrag && IsTextEdit() ) )
1429 // mba: clipboard always must contain absolute URLs (could be from alien source)
1430 pOLV->Read( *xStm, OUString(), EE_FORMAT_RTF, false, mpDocSh->GetHeaderAttributes() );
1431 bReturn = true;
1435 if( !bReturn )
1436 // mba: clipboard always must contain absolute URLs (could be from alien source)
1437 bReturn = SdrView::Paste( *xStm, OUString(), EE_FORMAT_RTF, maDropPos, pPage, nPasteOptions );
1442 if(!bReturn && CHECK_FORMAT_TRANS(SotClipboardFormatId::FILE_LIST))
1444 FileList aDropFileList;
1446 if( aDataHelper.GetFileList( SotClipboardFormatId::FILE_LIST, aDropFileList ) )
1448 maDropFileVector.clear();
1450 for( sal_uLong i = 0, nCount = aDropFileList.Count(); i < nCount; i++ )
1451 maDropFileVector.push_back( aDropFileList.GetFile( i ) );
1453 maDropInsertFileIdle.Start();
1456 bReturn = true;
1459 if(!bReturn && CHECK_FORMAT_TRANS(SotClipboardFormatId::SIMPLE_FILE))
1461 OUString aDropFile;
1463 if( aDataHelper.GetString( SotClipboardFormatId::SIMPLE_FILE, aDropFile ) )
1465 maDropFileVector.clear();
1466 maDropFileVector.push_back( aDropFile );
1467 maDropInsertFileIdle.Start();
1470 bReturn = true;
1473 if(!bReturn && !bLink && CHECK_FORMAT_TRANS(SotClipboardFormatId::STRING))
1475 if( ( SotClipboardFormatId::STRING == nFormat ) ||
1476 ( !aDataHelper.HasFormat( SotClipboardFormatId::SOLK ) &&
1477 !aDataHelper.HasFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK ) &&
1478 !aDataHelper.HasFormat( SotClipboardFormatId::FILENAME ) ) )
1480 OUString aOUString;
1482 if( aDataHelper.GetString( SotClipboardFormatId::STRING, aOUString ) )
1484 OutlinerView* pOLV = GetTextEditOutlinerView();
1486 if( pOLV )
1488 pOLV->InsertText( aOUString );
1489 bReturn = true;
1492 if( !bReturn )
1493 bReturn = SdrView::Paste( aOUString, maDropPos, pPage, nPasteOptions );
1498 MarkListHasChanged();
1499 mbIsDropAllowed = true;
1500 rDnDAction = mnAction;
1502 return bReturn;
1505 bool View::PasteRTFTable( ::tools::SvRef<SotStorageStream> xStm, SdrPage* pPage, SdrInsertFlags nPasteOptions )
1507 boost::scoped_ptr<SdDrawDocument> pModel(new SdDrawDocument( DOCUMENT_TYPE_IMPRESS, mpDocSh ));
1508 pModel->NewOrLoadCompleted(NEW_DOC);
1509 pModel->GetItemPool().SetDefaultMetric(SFX_MAPUNIT_100TH_MM);
1510 pModel->InsertPage(pModel->AllocPage(false));
1512 Reference< XComponent > xComponent( new SdXImpressDocument( pModel.get(), true ) );
1513 pModel->setUnoModel( Reference< XInterface >::query( xComponent ) );
1515 CreateTableFromRTF( *xStm, pModel.get() );
1516 bool bRet = Paste(*pModel, maDropPos, pPage, nPasteOptions, OUString(), OUString());
1518 xComponent->dispose();
1519 xComponent.clear();
1521 return bRet;
1524 } // end of namespace sd
1526 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */