1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_sd.hxx"
24
25 #include "View.hxx"
26 #include <com/sun/star/embed/XEmbedObjectClipboardCreator.hpp>
27 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
28 #include <com/sun/star/lang/XComponent.hpp>
29 #include <sot/filelist.hxx>
30 #include <unotools/pathoptions.hxx>
31 #include <editeng/editdata.hxx>
32 #include <svl/urlbmk.hxx>
33 #include <svx/xexch.hxx>
34 #include <svx/xflclit.hxx>
35 #include <svx/xlnclit.hxx>
36 #include <svx/svdpagv.hxx>
37 #include <editeng/eeitem.hxx>
38 #include <editeng/colritem.hxx>
39 #include <sfx2/docfile.hxx>
40 #include <svx/svditer.hxx>
41 #include <svx/svdogrp.hxx>
42 #include <svx/svdoole2.hxx>
43 #include <svx/svdograf.hxx>
44 #include <svx/svdetc.hxx>
45 #include <svx/svdundo.hxx>
46 #include <sfx2/app.hxx>
47 #include <svl/itempool.hxx>
48 #include <sot/clsids.hxx>
49 #include <svx/fmmodel.hxx>
50 #include <sot/formats.hxx>
51 #include <editeng/outliner.hxx>
52 #include <editeng/editeng.hxx>
53 #include <svx/obj3d.hxx>
54 #include <svx/e3dundo.hxx>
55 #include <svx/dbexch.hrc>
56 #include <svx/unomodel.hxx>
57 #include <unotools/streamwrap.hxx>
58 #include <vcl/metaact.hxx>
59 #include <svx/svxids.hrc>
60 #include <toolkit/helper/vclunohelper.hxx>
61 #include "DrawDocShell.hxx"
62 #include "fupoor.hxx"
63 #include "Window.hxx"
64 #include "sdxfer.hxx"
65 #include "sdpage.hxx"
66 #include "DrawViewShell.hxx"
67 #include "drawdoc.hxx"
68 #include "sdresid.hxx"
69 #include "strings.hrc"
70 #include "imapinfo.hxx"
71 #include "SlideSorterViewShell.hxx"
72 #include "strmname.h"
73 #include "unomodel.hxx"
74 #include "ViewClipboard.hxx"
75 #include <sfx2/ipclient.hxx>
76 #include <comphelper/storagehelper.hxx>
77 #include <comphelper/processfactory.hxx>
78 #include <tools/stream.hxx>
79 #include <vcl/cvtgrf.hxx>
80 #include <svx/sdrhittesthelper.hxx>
81 #include <svx/xbtmpit.hxx>
82
83 // --------------
84 // - Namespaces -
85 // --------------
86
87 using namespace ::com::sun::star;
88 using namespace ::com::sun::star::lang;
89 using namespace ::com::sun::star::uno;
90 using namespace ::com::sun::star::io;
91 using namespace ::com::sun::star::datatransfer;
92 using namespace ::com::sun::star::datatransfer::clipboard;
93
94 namespace sd {
95
96 #define CHECK_FORMAT_TRANS( _def_Type ) ( ( nFormat == (_def_Type) || !nFormat ) && aDataHelper.HasFormat( _def_Type ) )
97
98 /*************************************************************************
99 |*
100 |* Paste
101 |*
102 \************************************************************************/
103
104 // #83525#
105 struct ImpRememberOrigAndClone
106 {
107 SdrObject* pOrig;
108 SdrObject* pClone;
109 };
110
ImpGetClone(Container & aConnectorContainer,SdrObject * pConnObj)111 SdrObject* ImpGetClone(Container& aConnectorContainer, SdrObject* pConnObj)
112 {
113 for(sal_uInt32 a(0); a < aConnectorContainer.Count(); a++)
114 {
115 if(pConnObj == ((ImpRememberOrigAndClone*)aConnectorContainer.GetObject(a))->pOrig)
116 return ((ImpRememberOrigAndClone*)aConnectorContainer.GetObject(a))->pClone;
117 }
118 return 0L;
119 }
120
121 // #90129# restrict movement to WorkArea
ImpCheckInsertPos(Point & rPos,const Size & rSize,const Rectangle & rWorkArea)122 void ImpCheckInsertPos(Point& rPos, const Size& rSize, const Rectangle& rWorkArea)
123 {
124 if(!rWorkArea.IsEmpty())
125 {
126 Rectangle aMarkRect(Point(rPos.X() - (rSize.Width() / 2), rPos.Y() - (rSize.Height() / 2)), rSize);
127
128 if(!aMarkRect.IsInside(rWorkArea))
129 {
130 if(aMarkRect.Left() < rWorkArea.Left())
131 {
132 rPos.X() += rWorkArea.Left() - aMarkRect.Left();
133 }
134
135 if(aMarkRect.Right() > rWorkArea.Right())
136 {
137 rPos.X() -= aMarkRect.Right() - rWorkArea.Right();
138 }
139
140 if(aMarkRect.Top() < rWorkArea.Top())
141 {
142 rPos.Y() += rWorkArea.Top() - aMarkRect.Top();
143 }
144
145 if(aMarkRect.Bottom() > rWorkArea.Bottom())
146 {
147 rPos.Y() -= aMarkRect.Bottom() - rWorkArea.Bottom();
148 }
149 }
150 }
151 }
152
InsertMetaFile(TransferableDataHelper & rDataHelper,const Point & rPos,ImageMap * pImageMap,bool bOptimize)153 bool View::InsertMetaFile( TransferableDataHelper& rDataHelper, const Point& rPos, ImageMap* pImageMap, bool bOptimize )
154 {
155 GDIMetaFile aMtf;
156
157 if( !rDataHelper.GetGDIMetaFile( FORMAT_GDIMETAFILE, aMtf ) )
158 return false;
159
160 /*
161 SvFileStream aSvOutputStream( String( RTL_CONSTASCII_USTRINGPARAM( "/tmp/test.png" ) ), STREAM_WRITE | STREAM_TRUNC );
162 Graphic aMtfGraphic( aMtf );
163 Size aPreviewSizePixel( OutputDevice::LogicToLogic( aMtf.GetPrefSize(), aMtf.GetPrefMapMode(), MAP_PIXEL ) );
164
165 if( aPreviewSizePixel.Width() && aPreviewSizePixel.Height() )
166 {
167 const double fWH = static_cast< double >( aPreviewSizePixel.Width() ) / static_cast< double >( aPreviewSizePixel.Height() );
168
169 if( fWH <= 1.0 )
170 aPreviewSizePixel.Width() = static_cast< long >( 128.0 * fWH ), aPreviewSizePixel.Height() = 128;
171 else
172 aPreviewSizePixel.Width() = 128, aPreviewSizePixel.Height() = static_cast< long >( 128.0 / fWH );
173
174 if( GraphicConverter::Export( aSvOutputStream, aMtfGraphic.GetBitmapEx( &aPreviewSizePixel ), CVT_PNG ) )
175 {
176 // handle errror case here
177 }
178 else
179 {
180 // Success
181 }
182 }
183 */
184 bool bVector = false;
185 Graphic aGraphic;
186
187 // check if metafile only contains a pixel image, if so insert a bitmap instead
188 if( bOptimize )
189 {
190 MetaAction* pAction = aMtf.FirstAction();
191 while( pAction && !bVector )
192 {
193 switch( pAction->GetType() )
194 {
195 case META_POINT_ACTION:
196 case META_LINE_ACTION:
197 case META_RECT_ACTION:
198 case META_ROUNDRECT_ACTION:
199 case META_ELLIPSE_ACTION:
200 case META_ARC_ACTION:
201 case META_PIE_ACTION:
202 case META_CHORD_ACTION:
203 case META_POLYLINE_ACTION:
204 case META_POLYGON_ACTION:
205 case META_POLYPOLYGON_ACTION:
206 case META_TEXT_ACTION:
207 case META_TEXTARRAY_ACTION:
208 case META_STRETCHTEXT_ACTION:
209 case META_TEXTRECT_ACTION:
210 case META_GRADIENT_ACTION:
211 case META_HATCH_ACTION:
212 case META_WALLPAPER_ACTION:
213 case META_EPS_ACTION:
214 case META_TEXTLINE_ACTION:
215 case META_FLOATTRANSPARENT_ACTION:
216 case META_GRADIENTEX_ACTION:
217 case META_BMPSCALEPART_ACTION:
218 case META_BMPEXSCALEPART_ACTION:
219 bVector = true;
220 break;
221 case META_BMP_ACTION:
222 case META_BMPSCALE_ACTION:
223 case META_BMPEX_ACTION:
224 case META_BMPEXSCALE_ACTION:
225 if( aGraphic.GetType() != GRAPHIC_NONE )
226 {
227 bVector = true;
228 }
229 else switch( pAction->GetType() )
230 {
231 case META_BMP_ACTION:
232 {
233 MetaBmpAction* pBmpAction = dynamic_cast< MetaBmpAction* >( pAction );
234 if( pBmpAction )
235 aGraphic = Graphic( pBmpAction->GetBitmap() );
236 }
237 break;
238 case META_BMPSCALE_ACTION:
239 {
240 MetaBmpScaleAction* pBmpScaleAction = dynamic_cast< MetaBmpScaleAction* >( pAction );
241 if( pBmpScaleAction )
242 aGraphic = Graphic( pBmpScaleAction->GetBitmap() );
243 }
244 break;
245 case META_BMPEX_ACTION:
246 {
247 MetaBmpExAction* pBmpExAction = dynamic_cast< MetaBmpExAction* >( pAction );
248 if( pBmpExAction )
249 aGraphic = Graphic( pBmpExAction->GetBitmapEx() );
250 }
251 break;
252 case META_BMPEXSCALE_ACTION:
253 {
254 MetaBmpExScaleAction* pBmpExScaleAction = dynamic_cast< MetaBmpExScaleAction* >( pAction );
255 if( pBmpExScaleAction )
256 aGraphic = Graphic( pBmpExScaleAction->GetBitmapEx() );
257 }
258 break;
259 }
260 }
261
262 pAction = aMtf.NextAction();
263 }
264 }
265
266 // it is not a vector metafile but it also has no graphic?
267 if( !bVector && (aGraphic.GetType() == GRAPHIC_NONE) )
268 bVector = true;
269
270 // #90129# restrict movement to WorkArea
271 Point aInsertPos( rPos );
272 Size aImageSize;
273 aImageSize = bVector ? aMtf.GetPrefSize() : aGraphic.GetSizePixel();
274 ImpCheckInsertPos(aInsertPos, aImageSize, GetWorkArea());
275
276 if( bVector )
277 aGraphic = Graphic( aMtf );
278
279 aGraphic.SetPrefMapMode( aMtf.GetPrefMapMode() );
280 aGraphic.SetPrefSize( aMtf.GetPrefSize() );
281 InsertGraphic( aGraphic, mnAction, aInsertPos, NULL, pImageMap );
282
283 return true;
284 }
285
InsertData(const TransferableDataHelper & rDataHelper,const Point & rPos,sal_Int8 & rDnDAction,sal_Bool bDrag,sal_uLong nFormat,sal_uInt16 nPage,sal_uInt16 nLayer)286 sal_Bool View::InsertData( const TransferableDataHelper& rDataHelper,
287 const Point& rPos, sal_Int8& rDnDAction, sal_Bool bDrag,
288 sal_uLong nFormat, sal_uInt16 nPage, sal_uInt16 nLayer )
289 {
290 maDropPos = rPos;
291 mnAction = rDnDAction;
292 mbIsDropAllowed = sal_False;
293
294 TransferableDataHelper aDataHelper( rDataHelper );
295 SdrObject* pPickObj = NULL;
296 SdPage* pPage = NULL;
297 ImageMap* pImageMap = NULL;
298 bool bReturn = false;
299 sal_Bool bLink = ( ( mnAction & DND_ACTION_LINK ) != 0 );
300 sal_Bool bCopy = ( ( ( mnAction & DND_ACTION_COPY ) != 0 ) || bLink );
301 sal_uLong nPasteOptions = SDRINSERT_SETDEFLAYER;
302
303 if (mpViewSh != NULL)
304 {
305 OSL_ASSERT (mpViewSh->GetViewShell()!=NULL);
306 SfxInPlaceClient* pIpClient = mpViewSh->GetViewShell()->GetIPClient();
307 if( mpViewSh->ISA(::sd::slidesorter::SlideSorterViewShell)
308 || (pIpClient!=NULL && pIpClient->IsObjectInPlaceActive()))
309 nPasteOptions |= SDRINSERT_DONTMARK;
310 }
311
312 if( bDrag )
313 {
314 SdrPageView* pPV = NULL;
315 PickObj( rPos, getHitTolLog(), pPickObj, pPV );
316 }
317
318 if( nPage != SDRPAGE_NOTFOUND )
319 pPage = (SdPage*) mpDoc->GetPage( nPage );
320
321 SdTransferable* pOwnData = NULL;
322 SdTransferable* pImplementation = SdTransferable::getImplementation( aDataHelper.GetTransferable() );
323
324 if(pImplementation && (rDnDAction & DND_ACTION_LINK))
325 {
326 // suppress own data when it's intention is to use it as fill information
327 pImplementation = 0;
328 }
329
330 // try to get own transfer data
331 if( pImplementation )
332 {
333 if( SD_MOD()->pTransferClip == (SdTransferable*) pImplementation )
334 pOwnData = SD_MOD()->pTransferClip;
335 else if( SD_MOD()->pTransferDrag == (SdTransferable*) pImplementation )
336 pOwnData = SD_MOD()->pTransferDrag;
337 else if( SD_MOD()->pTransferSelection == (SdTransferable*) pImplementation )
338 pOwnData = SD_MOD()->pTransferSelection;
339 }
340
341 // ImageMap?
342 if( !pOwnData && aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVIM ) )
343 {
344 SotStorageStreamRef xStm;
345
346 if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_SVIM, xStm ) )
347 {
348 pImageMap = new ImageMap;
349 // mba: clipboard always must contain absolute URLs (could be from alien source)
350 pImageMap->Read( *xStm, String() );
351 }
352 }
353
354 bool bTable = false;
355 // check special cases for pasting table formats as RTL
356 if( !bLink && (!nFormat || (nFormat == SOT_FORMAT_RTF)) )
357 {
358 // if the objekt supports rtf and there is a table involved, default is to create a table
359 if( aDataHelper.HasFormat( SOT_FORMAT_RTF ) && ! aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ) )
360 {
361 SotStorageStreamRef xStm;
362
363 if( aDataHelper.GetSotStorageStream( FORMAT_RTF, xStm ) )
364 {
365 xStm->Seek( 0 );
366
367 ByteString aLine;
368 while( xStm->ReadLine(aLine) )
369 {
370 xub_StrLen x = aLine.Search( "\\trowd" );
371 if( x != STRING_NOTFOUND )
372 {
373 bTable = true;
374 nFormat = FORMAT_RTF;
375 break;
376 }
377 }
378 }
379 }
380 }
381
382 // Changed the whole decision tree to be dependent of bReturn as a flag that
383 // the work was done; this allows to check multiple formats and not just fail
384 // when a CHECK_FORMAT_TRANS(*format*) detected format does not work. This is
385 // e.g. necessary for FORMAT_BITMAP
386 if( pOwnData && !nFormat )
387 {
388 const View* pSourceView = pOwnData->GetView();
389
390 if( pOwnData->GetDocShell() && pOwnData->IsPageTransferable() && ISA( View ) )
391 {
392 mpClipboard->HandlePageDrop (*pOwnData);
393 }
394 else if( pSourceView )
395 {
396 if( pSourceView == this )
397 {
398 // same view
399 if( nLayer != SDRLAYER_NOTFOUND )
400 {
401 // drop on layer tab bar
402 SdrLayerAdmin& rLayerAdmin = mpDoc->GetLayerAdmin();
403 SdrLayer* pLayer = rLayerAdmin.GetLayerPerID( nLayer );
404 SdrPageView* pPV = GetSdrPageView();
405 String aLayer( pLayer->GetName() );
406
407 if( !pPV->IsLayerLocked( aLayer ) )
408 {
409 pOwnData->SetInternalMove( sal_True );
410 SortMarkedObjects();
411
412 for( sal_uLong nM = 0; nM < GetMarkedObjectCount(); nM++ )
413 {
414 SdrMark* pM = GetSdrMarkByIndex( nM );
415 SdrObject* pO = pM->GetMarkedSdrObj();
416
417 if( pO )
418 {
419 // #i11702#
420 if( IsUndoEnabled() )
421 {
422 BegUndo(String(SdResId(STR_MODIFYLAYER)));
423 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectLayerChange(*pO, pO->GetLayer(), (SdrLayerID)nLayer));
424 EndUndo();
425 }
426
427 pO->SetLayer( (SdrLayerID) nLayer );
428 }
429 }
430
431 bReturn = true;
432 }
433 }
434 else
435 {
436 SdrPageView* pPV = GetSdrPageView();
437 sal_Bool bDropOnTabBar = sal_True;
438
439 if( !pPage && pPV->GetPage()->GetPageNum() != mnDragSrcPgNum )
440 {
441 pPage = (SdPage*) pPV->GetPage();
442 bDropOnTabBar = sal_False;
443 }
444
445 if( pPage )
446 {
447 // drop on other page
448 String aActiveLayer( GetActiveLayer() );
449
450 if( !pPV->IsLayerLocked( aActiveLayer ) )
451 {
452 if( !IsPresObjSelected() )
453 {
454 SdrMarkList* pMarkList;
455
456 if( (mnDragSrcPgNum != SDRPAGE_NOTFOUND) && (mnDragSrcPgNum != pPV->GetPage()->GetPageNum()) )
457 {
458 pMarkList = mpDragSrcMarkList;
459 }
460 else
461 {
462 // actual mark list is used
463 pMarkList = new SdrMarkList( GetMarkedObjectList());
464 }
465
466 pMarkList->ForceSort();
467
468 // #83525# stuff to remember originals and clones
469 Container aConnectorContainer(0);
470 sal_uInt32 a, nConnectorCount(0L);
471 Point aCurPos;
472
473 // calculate real position of current
474 // source objects, if necessary (#103207)
475 if( pOwnData == SD_MOD()->pTransferSelection )
476 {
477 Rectangle aCurBoundRect;
478
479 if( pMarkList->TakeBoundRect( pPV, aCurBoundRect ) )
480 aCurPos = aCurBoundRect.TopLeft();
481 else
482 aCurPos = pOwnData->GetStartPos();
483 }
484 else
485 aCurPos = pOwnData->GetStartPos();
486
487 const Size aVector( maDropPos.X() - aCurPos.X(), maDropPos.Y() - aCurPos.Y() );
488
489 for(a = 0; a < pMarkList->GetMarkCount(); a++)
490 {
491 SdrMark* pM = pMarkList->GetMark(a);
492 SdrObject* pObj = pM->GetMarkedSdrObj()->Clone();
493
494 if(pObj)
495 {
496 if(!bDropOnTabBar)
497 {
498 // #83525# do a NbcMove(...) instead of setting SnapRects here
499 pObj->NbcMove(aVector);
500 }
501
502 pPage->InsertObject(pObj);
503
504 if( IsUndoEnabled() )
505 {
506 BegUndo(String(SdResId(STR_UNDO_DRAGDROP)));
507 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pObj));
508 EndUndo();
509 }
510
511 // #83525#
512 ImpRememberOrigAndClone* pRem = new ImpRememberOrigAndClone;
513 pRem->pOrig = pM->GetMarkedSdrObj();
514 pRem->pClone = pObj;
515 aConnectorContainer.Insert(pRem, CONTAINER_APPEND);
516
517 if(pObj->ISA(SdrEdgeObj))
518 nConnectorCount++;
519 }
520 }
521
522 // #83525# try to re-establish connections at clones
523 if(nConnectorCount)
524 {
525 for(a = 0; a < aConnectorContainer.Count(); a++)
526 {
527 ImpRememberOrigAndClone* pRem = (ImpRememberOrigAndClone*)aConnectorContainer.GetObject(a);
528
529 if(pRem->pClone->ISA(SdrEdgeObj))
530 {
531 SdrEdgeObj* pOrigEdge = (SdrEdgeObj*)pRem->pOrig;
532 SdrEdgeObj* pCloneEdge = (SdrEdgeObj*)pRem->pClone;
533
534 // test first connection
535 SdrObjConnection& rConn0 = pOrigEdge->GetConnection(sal_False);
536 SdrObject* pConnObj = rConn0.GetObject();
537 if(pConnObj)
538 {
539 SdrObject* pConnClone = ImpGetClone(aConnectorContainer, pConnObj);
540 if(pConnClone)
541 {
542 // if dest obj was cloned, too, re-establish connection
543 pCloneEdge->ConnectToNode(sal_False, pConnClone);
544 pCloneEdge->GetConnection(sal_False).SetConnectorId(rConn0.GetConnectorId());
545 }
546 else
547 {
548 // set position of connection point of original connected object
549 const SdrGluePointList* pGlueList = pConnObj->GetGluePointList();
550 if(pGlueList)
551 {
552 sal_uInt16 nInd = pGlueList->FindGluePoint(rConn0.GetConnectorId());
553
554 if(SDRGLUEPOINT_NOTFOUND != nInd)
555 {
556 const SdrGluePoint& rGluePoint = (*pGlueList)[nInd];
557 Point aPosition = rGluePoint.GetAbsolutePos(*pConnObj);
558 aPosition.X() += aVector.A();
559 aPosition.Y() += aVector.B();
560 pCloneEdge->SetTailPoint(sal_False, aPosition);
561 }
562 }
563 }
564 }
565
566 // test second connection
567 SdrObjConnection& rConn1 = pOrigEdge->GetConnection(sal_True);
568 pConnObj = rConn1.GetObject();
569 if(pConnObj)
570 {
571 SdrObject* pConnClone = ImpGetClone(aConnectorContainer, pConnObj);
572 if(pConnClone)
573 {
574 // if dest obj was cloned, too, re-establish connection
575 pCloneEdge->ConnectToNode(sal_True, pConnClone);
576 pCloneEdge->GetConnection(sal_True).SetConnectorId(rConn1.GetConnectorId());
577 }
578 else
579 {
580 // set position of connection point of original connected object
581 const SdrGluePointList* pGlueList = pConnObj->GetGluePointList();
582 if(pGlueList)
583 {
584 sal_uInt16 nInd = pGlueList->FindGluePoint(rConn1.GetConnectorId());
585
586 if(SDRGLUEPOINT_NOTFOUND != nInd)
587 {
588 const SdrGluePoint& rGluePoint = (*pGlueList)[nInd];
589 Point aPosition = rGluePoint.GetAbsolutePos(*pConnObj);
590 aPosition.X() += aVector.A();
591 aPosition.Y() += aVector.B();
592 pCloneEdge->SetTailPoint(sal_True, aPosition);
593 }
594 }
595 }
596 }
597 }
598 }
599 }
600
601 // #83525# cleanup remember classes
602 for(a = 0; a < aConnectorContainer.Count(); a++)
603 delete (ImpRememberOrigAndClone*)aConnectorContainer.GetObject(a);
604
605 if( pMarkList != mpDragSrcMarkList )
606 delete pMarkList;
607
608 bReturn = true;
609 }
610 else
611 {
612 maDropErrorTimer.Start();
613 bReturn = false;
614 }
615 }
616 }
617 else
618 {
619 pOwnData->SetInternalMove( sal_True );
620 MoveAllMarked( Size( maDropPos.X() - pOwnData->GetStartPos().X(),
621 maDropPos.Y() - pOwnData->GetStartPos().Y() ), bCopy );
622 bReturn = true;
623 }
624 }
625 }
626 else
627 {
628 // different views
629 if( !pSourceView->IsPresObjSelected() )
630 {
631 // model is owned by from AllocModel() created DocShell
632 SdDrawDocument* pSourceDoc = (SdDrawDocument*) pSourceView->GetModel();
633 pSourceDoc->CreatingDataObj( pOwnData );
634 SdDrawDocument* pModel = (SdDrawDocument*) pSourceView->GetAllMarkedModel();
635 bReturn = Paste( *pModel, maDropPos, pPage, nPasteOptions );
636
637 if( !pPage )
638 pPage = (SdPage*) GetSdrPageView()->GetPage();
639
640 String aLayout( pPage->GetLayoutName() );
641 aLayout.Erase( aLayout.SearchAscii( SD_LT_SEPARATOR ) );
642 pPage->SetPresentationLayout( aLayout, sal_False, sal_False );
643 pSourceDoc->CreatingDataObj( NULL );
644 }
645 else
646 {
647 maDropErrorTimer.Start();
648 bReturn = false;
649 }
650 }
651 }
652 else
653 {
654 SdDrawDocument* pWorkModel = (SdDrawDocument*) pOwnData->GetWorkDocument();
655 SdPage* pWorkPage = (SdPage*) pWorkModel->GetSdPage( 0, PK_STANDARD );
656
657 pWorkPage->SetRectsDirty();
658
659 // #120393# Clipboard data uses full object geometry range
660 const Size aSize( pWorkPage->GetAllObjBoundRect().GetSize() );
661
662 maDropPos.X() = pOwnData->GetStartPos().X() + ( aSize.Width() >> 1 );
663 maDropPos.Y() = pOwnData->GetStartPos().Y() + ( aSize.Height() >> 1 );
664
665 // delete pages, that are not of any interest for us
666 for( long i = ( pWorkModel->GetPageCount() - 1 ); i >= 0; i-- )
667 {
668 SdPage* pP = static_cast< SdPage* >( pWorkModel->GetPage( (sal_uInt16) i ) );
669
670 if( pP->GetPageKind() != PK_STANDARD )
671 pWorkModel->DeletePage( (sal_uInt16) i );
672 }
673
674 bReturn = Paste( *pWorkModel, maDropPos, pPage, nPasteOptions );
675
676 if( !pPage )
677 pPage = (SdPage*) GetSdrPageView()->GetPage();
678
679 String aLayout(pPage->GetLayoutName());
680 aLayout.Erase(aLayout.SearchAscii(SD_LT_SEPARATOR));
681 pPage->SetPresentationLayout( aLayout, sal_False, sal_False );
682 }
683 }
684
685 if(!bReturn && CHECK_FORMAT_TRANS( SOT_FORMATSTR_ID_DRAWING ))
686 {
687 SotStorageStreamRef xStm;
688
689 if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_DRAWING, xStm ) )
690 {
691 sal_Bool bChanged = sal_False;
692
693 DrawDocShellRef xShell = new DrawDocShell(SFX_CREATE_MODE_INTERNAL);
694 xShell->DoInitNew(0);
695
696 SdDrawDocument* pModel = xShell->GetDoc();
697 pModel->InsertPage(pModel->AllocPage(false));
698
699 Reference< XComponent > xComponent( xShell->GetModel(), UNO_QUERY );
700 xStm->Seek( 0 );
701
702 com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream( new utl::OInputStreamWrapper( *xStm ) );
703 bReturn = SvxDrawingLayerImport( pModel, xInputStream, xComponent, "com.sun.star.comp.Impress.XMLOasisImporter" );
704
705 if( pModel->GetPageCount() == 0 )
706 {
707 DBG_ERROR("empty or invalid drawing xml document on clipboard!" );
708 }
709 else
710 {
711 if( bReturn )
712 {
713 if( pModel->GetSdPage( 0, PK_STANDARD )->GetObjCount() == 1 )
714 {
715 // only one object
716 SdrObject* pObj = pModel->GetSdPage( 0, PK_STANDARD )->GetObj( 0 );
717 SdrObject* pPickObj2 = NULL;
718 SdrPageView* pPV = NULL;
719 PickObj( rPos, getHitTolLog(), pPickObj2, pPV );
720
721 if( ( mnAction & DND_ACTION_MOVE ) && pPickObj2 && pObj )
722 {
723 // replace object
724 SdrObject* pNewObj = pObj->Clone();
725 Rectangle aPickObjRect( pPickObj2->GetCurrentBoundRect() );
726 Size aPickObjSize( aPickObjRect.GetSize() );
727 Point aVec( aPickObjRect.TopLeft() );
728 Rectangle aObjRect( pNewObj->GetCurrentBoundRect() );
729 Size aObjSize( aObjRect.GetSize() );
730
731 Fraction aScaleWidth( aPickObjSize.Width(), aObjSize.Width() );
732 Fraction aScaleHeight( aPickObjSize.Height(), aObjSize.Height() );
733 pNewObj->NbcResize( aObjRect.TopLeft(), aScaleWidth, aScaleHeight );
734
735 aVec -= aObjRect.TopLeft();
736 pNewObj->NbcMove( Size( aVec.X(), aVec.Y() ) );
737
738 const bool bUndo = IsUndoEnabled();
739
740 if( bUndo )
741 BegUndo( String( SdResId(STR_UNDO_DRAGDROP ) ) );
742 pNewObj->NbcSetLayer( pPickObj->GetLayer() );
743 SdrPage* pWorkPage = GetSdrPageView()->GetPage();
744 pWorkPage->InsertObject( pNewObj );
745 if( bUndo )
746 {
747 AddUndo( mpDoc->GetSdrUndoFactory().CreateUndoNewObject( *pNewObj ) );
748 AddUndo( mpDoc->GetSdrUndoFactory().CreateUndoDeleteObject( *pPickObj2 ) );
749 }
750 pWorkPage->RemoveObject( pPickObj2->GetOrdNum() );
751
752 if( bUndo )
753 {
754 EndUndo();
755 }
756 else
757 {
758 SdrObject::Free(pPickObj2 );
759 }
760 bChanged = sal_True;
761 mnAction = DND_ACTION_COPY;
762 }
763 else if( ( mnAction & DND_ACTION_LINK ) && pPickObj && pObj && !pPickObj->ISA( SdrGrafObj ) && !pPickObj->ISA( SdrOle2Obj ) )
764 {
765 SfxItemSet aSet( mpDoc->GetPool() );
766
767 // set new attributes to object
768 const bool bUndo = IsUndoEnabled();
769 if( bUndo )
770 {
771 BegUndo( String( SdResId( STR_UNDO_DRAGDROP ) ) );
772 AddUndo( mpDoc->GetSdrUndoFactory().CreateUndoAttrObject( *pPickObj ) );
773 }
774
775 aSet.Put( pObj->GetMergedItemSet() );
776
777 // Eckenradius soll nicht uebernommen werden.
778 // In der Gallery stehen Farbverlauefe (Rechtecke)
779 // welche den Eckenradius == 0 haben. Dieser soll
780 // nicht auf das Objekt uebertragen werden.
781 aSet.ClearItem( SDRATTR_ECKENRADIUS );
782
783 const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pObj);
784
785 if(pSdrGrafObj)
786 {
787 // If we have a graphic as source object, use it's graphic
788 // content as fill style
789 aSet.Put(XFillStyleItem(XFILL_BITMAP));
790 aSet.Put(XFillBitmapItem(&mpDoc->GetPool(), pSdrGrafObj->GetGraphic()));
791 }
792
793 pPickObj->SetMergedItemSetAndBroadcast( aSet );
794
795 if( pPickObj->ISA( E3dObject ) && pObj->ISA( E3dObject ) )
796 {
797 // Zusaetzlich 3D Attribute handeln
798 SfxItemSet aNewSet( mpDoc->GetPool(), SID_ATTR_3D_START, SID_ATTR_3D_END, 0 );
799 SfxItemSet aOldSet( mpDoc->GetPool(), SID_ATTR_3D_START, SID_ATTR_3D_END, 0 );
800
801 aOldSet.Put(pPickObj->GetMergedItemSet());
802 aNewSet.Put( pObj->GetMergedItemSet() );
803
804 if( bUndo )
805 AddUndo( new E3dAttributesUndoAction( *mpDoc, this, (E3dObject*) pPickObj, aNewSet, aOldSet, sal_False ) );
806 pPickObj->SetMergedItemSetAndBroadcast( aNewSet );
807 }
808
809 if( bUndo )
810 EndUndo();
811 bChanged = sal_True;
812 }
813 }
814 }
815
816 if( !bChanged )
817 {
818 SdrPage* pWorkPage = pModel->GetSdPage( 0, PK_STANDARD );
819
820 pWorkPage->SetRectsDirty();
821
822 if( pOwnData )
823 {
824 // #120393# Clipboard data uses full object geometry range
825 const Size aSize( pWorkPage->GetAllObjBoundRect().GetSize() );
826
827 maDropPos.X() = pOwnData->GetStartPos().X() + ( aSize.Width() >> 1 );
828 maDropPos.Y() = pOwnData->GetStartPos().Y() + ( aSize.Height() >> 1 );
829 }
830
831 bReturn = Paste( *pModel, maDropPos, pPage, nPasteOptions );
832 }
833
834 xShell->DoClose();
835 }
836 }
837 }
838
839 if(!bReturn && CHECK_FORMAT_TRANS(SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE))
840 {
841 ::rtl::OUString aOUString;
842
843 if( aDataHelper.GetString( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE, aOUString ) )
844 {
845 SdrObject* pObj = CreateFieldControl( aOUString );
846
847 if( pObj )
848 {
849 Rectangle aRect( pObj->GetLogicRect() );
850 Size aSize( aRect.GetSize() );
851
852 maDropPos.X() -= ( aSize.Width() >> 1 );
853 maDropPos.Y() -= ( aSize.Height() >> 1 );
854
855 aRect.SetPos( maDropPos );
856 pObj->SetLogicRect( aRect );
857 InsertObjectAtView( pObj, *GetSdrPageView(), SDRINSERT_SETDEFLAYER );
858 bReturn = true;
859 }
860 }
861 }
862
863 if(!bReturn &&
864 !bLink &&
865 (CHECK_FORMAT_TRANS(SOT_FORMATSTR_ID_EMBED_SOURCE) || CHECK_FORMAT_TRANS(SOT_FORMATSTR_ID_EMBEDDED_OBJ)) &&
866 aDataHelper.HasFormat(SOT_FORMATSTR_ID_OBJECTDESCRIPTOR))
867 {
868 //TODO/LATER: is it possible that this format is binary?! (from old versions of SO)
869 uno::Reference < io::XInputStream > xStm;
870 TransferableObjectDescriptor aObjDesc;
871
872 if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) &&
873 ( aDataHelper.GetInputStream( nFormat ? nFormat : SOT_FORMATSTR_ID_EMBED_SOURCE, xStm ) ||
874 aDataHelper.GetInputStream( SOT_FORMATSTR_ID_EMBEDDED_OBJ, xStm ) ) )
875 {
876 if( mpDoc->GetDocSh() && ( mpDoc->GetDocSh()->GetClassName() == aObjDesc.maClassName ) )
877 {
878 uno::Reference < embed::XStorage > xStore( ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm ) );
879 ::sd::DrawDocShellRef xDocShRef( new ::sd::DrawDocShell( SFX_CREATE_MODE_EMBEDDED, sal_True, mpDoc->GetDocumentType() ) );
880
881 // mba: BaseURL doesn't make sense for clipboard functionality
882 SfxMedium *pMedium = new SfxMedium( xStore, String() );
883 if( xDocShRef->DoLoad( pMedium ) )
884 {
885 SdDrawDocument* pModel = (SdDrawDocument*) xDocShRef->GetDoc();
886 SdPage* pWorkPage = (SdPage*) pModel->GetSdPage( 0, PK_STANDARD );
887
888 pWorkPage->SetRectsDirty();
889
890 if( pOwnData )
891 {
892 // #120393# Clipboard data uses full object geometry range
893 const Size aSize( pWorkPage->GetAllObjBoundRect().GetSize() );
894
895 maDropPos.X() = pOwnData->GetStartPos().X() + ( aSize.Width() >> 1 );
896 maDropPos.Y() = pOwnData->GetStartPos().Y() + ( aSize.Height() >> 1 );
897 }
898
899 // delete pages, that are not of any interest for us
900 for( long i = ( pModel->GetPageCount() - 1 ); i >= 0; i-- )
901 {
902 SdPage* pP = static_cast< SdPage* >( pModel->GetPage( (sal_uInt16) i ) );
903
904 if( pP->GetPageKind() != PK_STANDARD )
905 pModel->DeletePage( (sal_uInt16) i );
906 }
907
908 bReturn = Paste( *pModel, maDropPos, pPage, nPasteOptions );
909
910 if( !pPage )
911 pPage = (SdPage*) GetSdrPageView()->GetPage();
912
913 String aLayout(pPage->GetLayoutName());
914 aLayout.Erase(aLayout.SearchAscii(SD_LT_SEPARATOR));
915 pPage->SetPresentationLayout( aLayout, sal_False, sal_False );
916 }
917
918 xDocShRef->DoClose();
919 xDocShRef.Clear();
920
921 }
922 else
923 {
924 ::rtl::OUString aName;
925 uno::Reference < embed::XEmbeddedObject > xObj = mpDocSh->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
926 if ( xObj.is() )
927 {
928 svt::EmbeddedObjectRef aObjRef( xObj, aObjDesc.mnViewAspect );
929
930 // try to get the replacement image from the clipboard
931 Graphic aGraphic;
932 sal_uLong nGrFormat = 0;
933
934 // (wg. Selection Manager bei Trustet Solaris)
935 #ifndef SOLARIS
936 /*
937 if( aDataHelper.GetGraphic( SOT_FORMATSTR_ID_SVXB, aGraphic ) )
938 nGrFormat = SOT_FORMATSTR_ID_SVXB;
939 else if( aDataHelper.GetGraphic( FORMAT_GDIMETAFILE, aGraphic ) )
940 nGrFormat = SOT_FORMAT_GDIMETAFILE;
941 else if( aDataHelper.GetGraphic( FORMAT_BITMAP, aGraphic ) )
942 nGrFormat = SOT_FORMAT_BITMAP;
943 */
944 #endif
945
946 // insert replacement image ( if there is one ) into the object helper
947 if ( nGrFormat )
948 {
949 datatransfer::DataFlavor aDataFlavor;
950 SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
951 aObjRef.SetGraphic( aGraphic, aDataFlavor.MimeType );
952 }
953
954 Size aSize;
955 if ( aObjDesc.mnViewAspect == embed::Aspects::MSOLE_ICON )
956 {
957 if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() )
958 aSize = aObjDesc.maSize;
959 else
960 {
961 MapMode aMapMode( MAP_100TH_MM );
962 aSize = aObjRef.GetSize( &aMapMode );
963 }
964 }
965 else
966 {
967 awt::Size aSz;
968 MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( aObjDesc.mnViewAspect ) );
969 if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() )
970 {
971 Size aTmp( OutputDevice::LogicToLogic( aObjDesc.maSize, MAP_100TH_MM, aMapUnit ) );
972 aSz.Width = aTmp.Width();
973 aSz.Height = aTmp.Height();
974 xObj->setVisualAreaSize( aObjDesc.mnViewAspect, aSz );
975 }
976
977 try
978 {
979 aSz = xObj->getVisualAreaSize( aObjDesc.mnViewAspect );
980 }
981 catch( embed::NoVisualAreaSizeException& )
982 {
983 // if the size still was not set the default size will be set later
984 }
985
986 aSize = Size( aSz.Width, aSz.Height );
987
988 if( !aSize.Width() || !aSize.Height() )
989 {
990 aSize.Width() = 14100;
991 aSize.Height() = 10000;
992 aSize = OutputDevice::LogicToLogic( Size(14100, 10000), MAP_100TH_MM, aMapUnit );
993 aSz.Width = aSize.Width();
994 aSz.Height = aSize.Height();
995 xObj->setVisualAreaSize( aObjDesc.mnViewAspect, aSz );
996 }
997
998 aSize = OutputDevice::LogicToLogic( aSize, aMapUnit, MAP_100TH_MM );
999 }
1000
1001 Size aMaxSize( mpDoc->GetMaxObjSize() );
1002
1003 maDropPos.X() -= Min( aSize.Width(), aMaxSize.Width() ) >> 1;
1004 maDropPos.Y() -= Min( aSize.Height(), aMaxSize.Height() ) >> 1;
1005
1006 Rectangle aRect( maDropPos, aSize );
1007 SdrOle2Obj* pObj = new SdrOle2Obj( aObjRef, aName, aRect );
1008 SdrPageView* pPV = GetSdrPageView();
1009 sal_uLong nOptions = SDRINSERT_SETDEFLAYER;
1010
1011 if (mpViewSh!=NULL)
1012 {
1013 OSL_ASSERT (mpViewSh->GetViewShell()!=NULL);
1014 SfxInPlaceClient* pIpClient
1015 = mpViewSh->GetViewShell()->GetIPClient();
1016 if (pIpClient!=NULL && pIpClient->IsObjectInPlaceActive())
1017 nOptions |= SDRINSERT_DONTMARK;
1018 }
1019
1020 InsertObjectAtView( pObj, *pPV, nOptions );
1021
1022 if( pImageMap )
1023 pObj->InsertUserData( new SdIMapInfo( *pImageMap ) );
1024
1025 if ( pObj && pObj->IsChart() )
1026 {
1027 bool bDisableDataTableDialog = false;
1028 svt::EmbeddedObjectRef::TryRunningState( xObj );
1029 uno::Reference< beans::XPropertySet > xProps( xObj->getComponent(), uno::UNO_QUERY );
1030 if ( xProps.is() &&
1031 ( xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DisableDataTableDialog" ) ) ) >>= bDisableDataTableDialog ) &&
1032 bDisableDataTableDialog )
1033 {
1034 xProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DisableDataTableDialog" ) ),
1035 uno::makeAny( sal_False ) );
1036 xProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DisableComplexChartTypes" ) ),
1037 uno::makeAny( sal_False ) );
1038 uno::Reference< util::XModifiable > xModifiable( xProps, uno::UNO_QUERY );
1039 if ( xModifiable.is() )
1040 {
1041 xModifiable->setModified( sal_True );
1042 }
1043 }
1044 }
1045
1046 bReturn = true;
1047 }
1048 }
1049 }
1050 }
1051
1052 if(!bReturn &&
1053 !bLink &&
1054 (CHECK_FORMAT_TRANS(SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE) || CHECK_FORMAT_TRANS(SOT_FORMATSTR_ID_EMBED_SOURCE_OLE)) &&
1055 aDataHelper.HasFormat(SOT_FORMATSTR_ID_OBJECTDESCRIPTOR_OLE))
1056 {
1057 // online insert ole if format is forced or no gdi metafile is available
1058 if( (nFormat != 0) || !aDataHelper.HasFormat( FORMAT_GDIMETAFILE ) )
1059 {
1060 uno::Reference < io::XInputStream > xStm;
1061 TransferableObjectDescriptor aObjDesc;
1062
1063 if ( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR_OLE, aObjDesc ) )
1064 {
1065 uno::Reference < embed::XEmbeddedObject > xObj;
1066 ::rtl::OUString aName;
1067
1068 if ( aDataHelper.GetInputStream( nFormat ? nFormat : SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, xStm ) ||
1069 aDataHelper.GetInputStream( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, xStm ) )
1070 {
1071 xObj = mpDocSh->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
1072 }
1073 else
1074 {
1075 try
1076 {
1077 uno::Reference< embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
1078 uno::Reference < embed::XEmbedObjectClipboardCreator > xClipboardCreator(
1079 ::comphelper::getProcessServiceFactory()->createInstance(
1080 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.MSOLEObjectSystemCreator")) ),
1081 uno::UNO_QUERY_THROW );
1082
1083 embed::InsertedObjectInfo aInfo = xClipboardCreator->createInstanceInitFromClipboard(
1084 xTmpStor,
1085 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "DummyName" ) ),
1086 uno::Sequence< beans::PropertyValue >() );
1087
1088 // TODO/LATER: in future InsertedObjectInfo will be used to get container related information
1089 // for example whether the object should be an iconified one
1090 xObj = aInfo.Object;
1091 if ( xObj.is() )
1092 mpDocSh->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj, aName );
1093 }
1094 catch( uno::Exception& )
1095 {}
1096 }
1097
1098 if ( xObj.is() )
1099 {
1100 svt::EmbeddedObjectRef aObjRef( xObj, aObjDesc.mnViewAspect );
1101
1102 // try to get the replacement image from the clipboard
1103 Graphic aGraphic;
1104 sal_uLong nGrFormat = 0;
1105
1106 // (wg. Selection Manager bei Trustet Solaris)
1107 #ifndef SOLARIS
1108 if( aDataHelper.GetGraphic( SOT_FORMATSTR_ID_SVXB, aGraphic ) )
1109 nGrFormat = SOT_FORMATSTR_ID_SVXB;
1110 else if( aDataHelper.GetGraphic( FORMAT_GDIMETAFILE, aGraphic ) )
1111 nGrFormat = SOT_FORMAT_GDIMETAFILE;
1112 else if( aDataHelper.GetGraphic( FORMAT_BITMAP, aGraphic ) )
1113 nGrFormat = SOT_FORMAT_BITMAP;
1114 #endif
1115
1116 // insert replacement image ( if there is one ) into the object helper
1117 if ( nGrFormat )
1118 {
1119 datatransfer::DataFlavor aDataFlavor;
1120 SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
1121 aObjRef.SetGraphic( aGraphic, aDataFlavor.MimeType );
1122 }
1123
1124 Size aSize;
1125 if ( aObjDesc.mnViewAspect == embed::Aspects::MSOLE_ICON )
1126 {
1127 if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() )
1128 aSize = aObjDesc.maSize;
1129 else
1130 {
1131 MapMode aMapMode( MAP_100TH_MM );
1132 aSize = aObjRef.GetSize( &aMapMode );
1133 }
1134 }
1135 else
1136 {
1137 MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( aObjDesc.mnViewAspect ) );
1138
1139 awt::Size aSz;
1140 try{
1141 aSz = xObj->getVisualAreaSize( aObjDesc.mnViewAspect );
1142 }
1143 catch( embed::NoVisualAreaSizeException& )
1144 {
1145 // the default size will be set later
1146 }
1147
1148 if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() )
1149 {
1150 Size aTmp( OutputDevice::LogicToLogic( aObjDesc.maSize, MAP_100TH_MM, aMapUnit ) );
1151 if ( aSz.Width != aTmp.Width() || aSz.Height != aTmp.Height() )
1152 {
1153 aSz.Width = aTmp.Width();
1154 aSz.Height = aTmp.Height();
1155 xObj->setVisualAreaSize( aObjDesc.mnViewAspect, aSz );
1156 }
1157 }
1158
1159 aSize = Size( aSz.Width, aSz.Height );
1160
1161 if( !aSize.Width() || !aSize.Height() )
1162 {
1163 aSize = OutputDevice::LogicToLogic( Size(14100, 10000), MAP_100TH_MM, aMapUnit );
1164 aSz.Width = aSize.Width();
1165 aSz.Height = aSize.Height();
1166 xObj->setVisualAreaSize( aObjDesc.mnViewAspect, aSz );
1167 }
1168
1169 aSize = OutputDevice::LogicToLogic( aSize, aMapUnit, MAP_100TH_MM );
1170 }
1171
1172 Size aMaxSize( mpDoc->GetMaxObjSize() );
1173
1174 maDropPos.X() -= Min( aSize.Width(), aMaxSize.Width() ) >> 1;
1175 maDropPos.Y() -= Min( aSize.Height(), aMaxSize.Height() ) >> 1;
1176
1177 Rectangle aRect( maDropPos, aSize );
1178 SdrOle2Obj* pObj = new SdrOle2Obj( aObjRef, aName, aRect );
1179 SdrPageView* pPV = GetSdrPageView();
1180 sal_uLong nOptions = SDRINSERT_SETDEFLAYER;
1181
1182 if (mpViewSh!=NULL)
1183 {
1184 OSL_ASSERT (mpViewSh->GetViewShell()!=NULL);
1185 SfxInPlaceClient* pIpClient
1186 = mpViewSh->GetViewShell()->GetIPClient();
1187 if (pIpClient!=NULL && pIpClient->IsObjectInPlaceActive())
1188 nOptions |= SDRINSERT_DONTMARK;
1189 }
1190
1191 InsertObjectAtView( pObj, *pPV, nOptions );
1192
1193 if( pImageMap )
1194 pObj->InsertUserData( new SdIMapInfo( *pImageMap ) );
1195
1196 // let the object stay in loaded state after insertion
1197 pObj->Unload();
1198 bReturn = true;
1199 }
1200 }
1201 }
1202
1203 if( !bReturn && aDataHelper.HasFormat( FORMAT_GDIMETAFILE ) )
1204 {
1205 // if no object was inserted, insert a picture
1206 InsertMetaFile( aDataHelper, rPos, pImageMap, true );
1207 bReturn = true;
1208 }
1209 }
1210
1211 if(!bReturn && (!bLink || pPickObj) && CHECK_FORMAT_TRANS(SOT_FORMATSTR_ID_SVXB))
1212 {
1213 SotStorageStreamRef xStm;
1214
1215 if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_SVXB, xStm ) )
1216 {
1217 Point aInsertPos( rPos );
1218 Graphic aGraphic;
1219
1220 *xStm >> aGraphic;
1221
1222 if( pOwnData && pOwnData->GetWorkDocument() )
1223 {
1224 const SdDrawDocument* pWorkModel = pOwnData->GetWorkDocument();
1225 SdrPage* pWorkPage = (SdrPage*) ( ( pWorkModel->GetPageCount() > 1 ) ?
1226 pWorkModel->GetSdPage( 0, PK_STANDARD ) :
1227 pWorkModel->GetPage( 0 ) );
1228
1229 pWorkPage->SetRectsDirty();
1230
1231 // #120393# Clipboard data uses full object geometry range
1232 const Size aSize( pWorkPage->GetAllObjBoundRect().GetSize() );
1233
1234 aInsertPos.X() = pOwnData->GetStartPos().X() + ( aSize.Width() >> 1 );
1235 aInsertPos.Y() = pOwnData->GetStartPos().Y() + ( aSize.Height() >> 1 );
1236 }
1237
1238 // #90129# restrict movement to WorkArea
1239 Size aImageMapSize = OutputDevice::LogicToLogic(aGraphic.GetPrefSize(),
1240 aGraphic.GetPrefMapMode(), MapMode(MAP_100TH_MM));
1241
1242 ImpCheckInsertPos(aInsertPos, aImageMapSize, GetWorkArea());
1243
1244 InsertGraphic( aGraphic, mnAction, aInsertPos, NULL, pImageMap );
1245 bReturn = true;
1246 }
1247 }
1248
1249 if(!bReturn && (!bLink || pPickObj) && CHECK_FORMAT_TRANS(FORMAT_GDIMETAFILE))
1250 {
1251 Point aInsertPos( rPos );
1252
1253 if( pOwnData && pOwnData->GetWorkDocument() )
1254
1255 {
1256 const SdDrawDocument* pWorkModel = pOwnData->GetWorkDocument();
1257 SdrPage* pWorkPage = (SdrPage*) ( ( pWorkModel->GetPageCount() > 1 ) ?
1258 pWorkModel->GetSdPage( 0, PK_STANDARD ) :
1259 pWorkModel->GetPage( 0 ) );
1260
1261 pWorkPage->SetRectsDirty();
1262
1263 // #120393# Clipboard data uses full object geometry range
1264 const Size aSize( pWorkPage->GetAllObjBoundRect().GetSize() );
1265
1266 aInsertPos.X() = pOwnData->GetStartPos().X() + ( aSize.Width() >> 1 );
1267 aInsertPos.Y() = pOwnData->GetStartPos().Y() + ( aSize.Height() >> 1 );
1268 }
1269
1270 bReturn = InsertMetaFile( aDataHelper, aInsertPos, pImageMap, nFormat == 0 ? true : false ) ? sal_True : sal_False;
1271 }
1272
1273 if(!bReturn && (!bLink || pPickObj) && CHECK_FORMAT_TRANS(FORMAT_BITMAP))
1274 {
1275 BitmapEx aBmpEx;
1276
1277 // get basic Bitmap data
1278 aDataHelper.GetBitmapEx(FORMAT_BITMAP, aBmpEx);
1279
1280 if(aBmpEx.IsEmpty())
1281 {
1282 // if this did not work, try to get graphic formats and convert these to bitmap
1283 Graphic aGraphic;
1284
1285 if(aDataHelper.GetGraphic(FORMAT_GDIMETAFILE, aGraphic))
1286 {
1287 aBmpEx = aGraphic.GetBitmapEx();
1288 }
1289 else if(aDataHelper.GetGraphic(SOT_FORMATSTR_ID_SVXB, aGraphic))
1290 {
1291 aBmpEx = aGraphic.GetBitmapEx();
1292 }
1293 else if(aDataHelper.GetGraphic(FORMAT_BITMAP, aGraphic))
1294 {
1295 aBmpEx = aGraphic.GetBitmapEx();
1296 }
1297 }
1298
1299 if(!aBmpEx.IsEmpty())
1300 {
1301 Point aInsertPos( rPos );
1302
1303 if( pOwnData && pOwnData->GetWorkDocument() )
1304 {
1305 const SdDrawDocument* pWorkModel = pOwnData->GetWorkDocument();
1306 SdrPage* pWorkPage = (SdrPage*) ( ( pWorkModel->GetPageCount() > 1 ) ?
1307 pWorkModel->GetSdPage( 0, PK_STANDARD ) :
1308 pWorkModel->GetPage( 0 ) );
1309
1310 pWorkPage->SetRectsDirty();
1311
1312 // #120393# Clipboard data uses full object geometry range
1313 const Size aSize( pWorkPage->GetAllObjBoundRect().GetSize() );
1314
1315 aInsertPos.X() = pOwnData->GetStartPos().X() + ( aSize.Width() >> 1 );
1316 aInsertPos.Y() = pOwnData->GetStartPos().Y() + ( aSize.Height() >> 1 );
1317 }
1318
1319 // #90129# restrict movement to WorkArea
1320 Size aImageMapSize(aBmpEx.GetPrefSize());
1321 ImpCheckInsertPos(aInsertPos, aImageMapSize, GetWorkArea());
1322
1323 InsertGraphic( aBmpEx, mnAction, aInsertPos, NULL, pImageMap );
1324 bReturn = true;
1325 }
1326 }
1327
1328 if(!bReturn && pPickObj && CHECK_FORMAT_TRANS( SOT_FORMATSTR_ID_XFA ) )
1329 {
1330 SotStorageStreamRef xStm;
1331
1332 if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_XFA, xStm ) )
1333 {
1334 XFillExchangeData aFillData( XFillAttrSetItem( &mpDoc->GetPool() ) );
1335
1336 *xStm >> aFillData;
1337
1338 if( IsUndoEnabled() )
1339 {
1340 BegUndo( String( SdResId( STR_UNDO_DRAGDROP ) ) );
1341 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoAttrObject( *pPickObj ) );
1342 EndUndo();
1343 }
1344
1345 XFillAttrSetItem* pSetItem = aFillData.GetXFillAttrSetItem();
1346 SfxItemSet rSet = pSetItem->GetItemSet();
1347 XFillStyle eFill= ( (XFillStyleItem&) rSet.Get( XATTR_FILLSTYLE ) ).GetValue();
1348
1349 if( eFill == XFILL_SOLID || eFill == XFILL_NONE )
1350 {
1351 const XFillColorItem& rColItem = (XFillColorItem&) rSet.Get( XATTR_FILLCOLOR );
1352 Color aColor( rColItem.GetColorValue() );
1353 String aName( rColItem.GetName() );
1354 SfxItemSet aSet( mpDoc->GetPool() );
1355 sal_Bool bClosed = pPickObj->IsClosedObj();
1356 ::sd::Window* pWin = mpViewSh->GetActiveWindow();
1357 sal_uInt16 nHitLog = (sal_uInt16) pWin->PixelToLogic(
1358 Size(FuPoor::HITPIX, 0 ) ).Width();
1359 const long n2HitLog = nHitLog << 1;
1360 Point aHitPosR( rPos );
1361 Point aHitPosL( rPos );
1362 Point aHitPosT( rPos );
1363 Point aHitPosB( rPos );
1364 const SetOfByte* pVisiLayer = &GetSdrPageView()->GetVisibleLayers();
1365
1366 aHitPosR.X() += n2HitLog;
1367 aHitPosL.X() -= n2HitLog;
1368 aHitPosT.Y() += n2HitLog;
1369 aHitPosB.Y() -= n2HitLog;
1370
1371 if( bClosed &&
1372 SdrObjectPrimitiveHit(*pPickObj, aHitPosR, nHitLog, *GetSdrPageView(), pVisiLayer, false) &&
1373 SdrObjectPrimitiveHit(*pPickObj, aHitPosL, nHitLog, *GetSdrPageView(), pVisiLayer, false) &&
1374 SdrObjectPrimitiveHit(*pPickObj, aHitPosT, nHitLog, *GetSdrPageView(), pVisiLayer, false) &&
1375 SdrObjectPrimitiveHit(*pPickObj, aHitPosB, nHitLog, *GetSdrPageView(), pVisiLayer, false) )
1376 {
1377 // area fill
1378 if(eFill == XFILL_SOLID )
1379 aSet.Put(XFillColorItem(aName, aColor));
1380
1381 aSet.Put( XFillStyleItem( eFill ) );
1382 }
1383 else
1384 aSet.Put( XLineColorItem( aName, aColor ) );
1385
1386 // Textfarbe hinzufuegen
1387 pPickObj->SetMergedItemSetAndBroadcast( aSet );
1388 }
1389 }
1390 }
1391
1392 if(!bReturn && !bLink && CHECK_FORMAT_TRANS(SOT_FORMATSTR_ID_HTML))
1393 {
1394 SotStorageStreamRef xStm;
1395
1396 if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_HTML, xStm ) )
1397 {
1398 xStm->Seek( 0 );
1399 // mba: clipboard always must contain absolute URLs (could be from alien source)
1400 bReturn = SdrView::Paste( *xStm, String(), EE_FORMAT_HTML, maDropPos, pPage, nPasteOptions );
1401 }
1402 }
1403
1404 if(!bReturn && !bLink && CHECK_FORMAT_TRANS(SOT_FORMATSTR_ID_EDITENGINE))
1405 {
1406 SotStorageStreamRef xStm;
1407
1408 if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_EDITENGINE, xStm ) )
1409 {
1410 OutlinerView* pOLV = GetTextEditOutlinerView();
1411
1412 xStm->Seek( 0 );
1413
1414 if( pOLV )
1415 {
1416 Rectangle aRect( pOLV->GetOutputArea() );
1417 Point aPos( pOLV->GetWindow()->PixelToLogic( maDropPos ) );
1418
1419 if( aRect.IsInside( aPos ) || ( !bDrag && IsTextEdit() ) )
1420 {
1421 // mba: clipboard always must contain absolute URLs (could be from alien source)
1422 pOLV->Read( *xStm, String(), EE_FORMAT_BIN, sal_False, mpDocSh->GetHeaderAttributes() );
1423 bReturn = true;
1424 }
1425 }
1426
1427 if( !bReturn )
1428 // mba: clipboard always must contain absolute URLs (could be from alien source)
1429 bReturn = SdrView::Paste( *xStm, String(), EE_FORMAT_BIN, maDropPos, pPage, nPasteOptions );
1430 }
1431 }
1432
1433 if(!bReturn && !bLink && CHECK_FORMAT_TRANS(FORMAT_RTF))
1434 {
1435 SotStorageStreamRef xStm;
1436
1437 if( aDataHelper.GetSotStorageStream( FORMAT_RTF, xStm ) )
1438 {
1439 xStm->Seek( 0 );
1440
1441 if( bTable )
1442 {
1443 bReturn = PasteRTFTable( xStm, pPage, nPasteOptions );
1444 }
1445 else
1446 {
1447 OutlinerView* pOLV = GetTextEditOutlinerView();
1448
1449 if( pOLV )
1450 {
1451 Rectangle aRect( pOLV->GetOutputArea() );
1452 Point aPos( pOLV->GetWindow()->PixelToLogic( maDropPos ) );
1453
1454 if( aRect.IsInside( aPos ) || ( !bDrag && IsTextEdit() ) )
1455 {
1456 // mba: clipboard always must contain absolute URLs (could be from alien source)
1457 pOLV->Read( *xStm, String(), EE_FORMAT_RTF, sal_False, mpDocSh->GetHeaderAttributes() );
1458 bReturn = true;
1459 }
1460 }
1461
1462 if( !bReturn )
1463 // mba: clipboard always must contain absolute URLs (could be from alien source)
1464 bReturn = SdrView::Paste( *xStm, String(), EE_FORMAT_RTF, maDropPos, pPage, nPasteOptions );
1465 }
1466 }
1467 }
1468
1469 if(!bReturn && CHECK_FORMAT_TRANS(FORMAT_FILE_LIST))
1470 {
1471 FileList aDropFileList;
1472
1473 if( aDataHelper.GetFileList( FORMAT_FILE_LIST, aDropFileList ) )
1474 {
1475 maDropFileVector.clear();
1476
1477 for( sal_uLong i = 0, nCount = aDropFileList.Count(); i < nCount; i++ )
1478 maDropFileVector.push_back( aDropFileList.GetFile( i ) );
1479
1480 maDropInsertFileTimer.Start();
1481 }
1482
1483 bReturn = true;
1484 }
1485
1486 if(!bReturn && CHECK_FORMAT_TRANS(FORMAT_FILE))
1487 {
1488 String aDropFile;
1489
1490 if( aDataHelper.GetString( FORMAT_FILE, aDropFile ) )
1491 {
1492 maDropFileVector.clear();
1493 maDropFileVector.push_back( aDropFile );
1494 maDropInsertFileTimer.Start();
1495 }
1496
1497 bReturn = true;
1498 }
1499
1500 if(!bReturn && !bLink && CHECK_FORMAT_TRANS(FORMAT_STRING))
1501 {
1502 if( ( FORMAT_STRING == nFormat ) ||
1503 ( !aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) &&
1504 !aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) &&
1505 !aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILENAME ) ) )
1506 {
1507 ::rtl::OUString aOUString;
1508
1509 if( aDataHelper.GetString( FORMAT_STRING, aOUString ) )
1510 {
1511 OutlinerView* pOLV = GetTextEditOutlinerView();
1512
1513 if( pOLV )
1514 {
1515 pOLV->InsertText( aOUString );
1516 bReturn = true;
1517 }
1518
1519 if( !bReturn )
1520 bReturn = SdrView::Paste( aOUString, maDropPos, pPage, nPasteOptions );
1521 }
1522 }
1523 }
1524
1525 MarkListHasChanged();
1526 mbIsDropAllowed = sal_True;
1527 rDnDAction = mnAction;
1528 delete pImageMap;
1529
1530 return bReturn;
1531 }
1532
1533 extern void CreateTableFromRTF( SvStream& rStream, SdDrawDocument* pModel );
1534
PasteRTFTable(SotStorageStreamRef xStm,SdrPage * pPage,sal_uLong nPasteOptions)1535 bool View::PasteRTFTable( SotStorageStreamRef xStm, SdrPage* pPage, sal_uLong nPasteOptions )
1536 {
1537 SdDrawDocument* pModel = new SdDrawDocument( DOCUMENT_TYPE_IMPRESS, mpDocSh );
1538 pModel->NewOrLoadCompleted(NEW_DOC);
1539 pModel->GetItemPool().SetDefaultMetric(SFX_MAPUNIT_100TH_MM);
1540 pModel->InsertPage(pModel->AllocPage(false));
1541
1542 Reference< XComponent > xComponent( new SdXImpressDocument( pModel, sal_True ) );
1543 pModel->setUnoModel( Reference< XInterface >::query( xComponent ) );
1544
1545 CreateTableFromRTF( *xStm, pModel );
1546 bool bRet = Paste( *pModel, maDropPos, pPage, nPasteOptions );
1547
1548 xComponent->dispose();
1549 xComponent.clear();
1550
1551 delete pModel;
1552
1553 return bRet;
1554 }
1555
1556 } // end of namespace sd
1557