/src/libreoffice/sd/source/ui/view/sdview3.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #include <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 <editeng/editdata.hxx> |
27 | | #include <svx/xfillit0.hxx> |
28 | | #include <svx/xflclit.hxx> |
29 | | #include <svx/xlnclit.hxx> |
30 | | #include <svx/svdpagv.hxx> |
31 | | #include <sfx2/docfile.hxx> |
32 | | #include <sfx2/mieclip.hxx> |
33 | | #include <svx/svdoole2.hxx> |
34 | | #include <svx/svdograf.hxx> |
35 | | #include <svx/svdundo.hxx> |
36 | | #include <svl/itempool.hxx> |
37 | | #include <sot/formats.hxx> |
38 | | #include <editeng/outliner.hxx> |
39 | | #include <svx/obj3d.hxx> |
40 | | #include <svx/e3dundo.hxx> |
41 | | #include <svx/unomodel.hxx> |
42 | | #include <svx/ImageMapInfo.hxx> |
43 | | #include <unotools/streamwrap.hxx> |
44 | | #include <vcl/graph.hxx> |
45 | | #include <vcl/metaact.hxx> |
46 | | #include <vcl/metaactiontypes.hxx> |
47 | | #include <vcl/pdfread.hxx> |
48 | | #include <vcl/TypeSerializer.hxx> |
49 | | #include <svx/svxids.hrc> |
50 | | #include <toolkit/helper/vclunohelper.hxx> |
51 | | #include <svtools/embedhlp.hxx> |
52 | | #include <osl/diagnose.h> |
53 | | #include <DrawDocShell.hxx> |
54 | | #include <fupoor.hxx> |
55 | | #include <tablefunction.hxx> |
56 | | #include <Window.hxx> |
57 | | #include <sdxfer.hxx> |
58 | | #include <sdpage.hxx> |
59 | | #include <drawdoc.hxx> |
60 | | #include <sdmod.hxx> |
61 | | #include <sdresid.hxx> |
62 | | #include <strings.hrc> |
63 | | #include <NotesPanelViewShell.hxx> |
64 | | #include <SlideSorterViewShell.hxx> |
65 | | #include <unomodel.hxx> |
66 | | #include <ViewClipboard.hxx> |
67 | | #include <sfx2/ipclient.hxx> |
68 | | #include <sfx2/classificationhelper.hxx> |
69 | | #include <comphelper/scopeguard.hxx> |
70 | | #include <comphelper/sequenceashashmap.hxx> |
71 | | #include <comphelper/storagehelper.hxx> |
72 | | #include <comphelper/processfactory.hxx> |
73 | | #include <svx/sdrhittesthelper.hxx> |
74 | | #include <svx/xbtmpit.hxx> |
75 | | #include <memory> |
76 | | #include <SlideSorter.hxx> |
77 | | #include <controller/SlideSorterController.hxx> |
78 | | #include <controller/SlsClipboard.hxx> |
79 | | |
80 | | using namespace ::com::sun::star; |
81 | | using namespace ::com::sun::star::lang; |
82 | | using namespace ::com::sun::star::uno; |
83 | | using namespace ::com::sun::star::io; |
84 | | using namespace ::com::sun::star::datatransfer; |
85 | | |
86 | | namespace sd { |
87 | | |
88 | | /************************************************************************* |
89 | | |* |
90 | | |* Paste |
91 | | |* |
92 | | \************************************************************************/ |
93 | | |
94 | | namespace { |
95 | | |
96 | | struct ImpRememberOrigAndClone |
97 | | { |
98 | | SdrObject* pOrig; |
99 | | SdrObject* pClone; |
100 | | }; |
101 | | |
102 | | } |
103 | | |
104 | | static SdrObject* ImpGetClone(std::vector<ImpRememberOrigAndClone>& aConnectorContainer, SdrObject const * pConnObj) |
105 | 0 | { |
106 | 0 | for(const ImpRememberOrigAndClone& rImp : aConnectorContainer) |
107 | 0 | { |
108 | 0 | if(pConnObj == rImp.pOrig) |
109 | 0 | return rImp.pClone; |
110 | 0 | } |
111 | 0 | return nullptr; |
112 | 0 | } |
113 | | |
114 | | // restrict movement to WorkArea |
115 | | static void ImpCheckInsertPos(Point& rPos, const Size& rSize, const ::tools::Rectangle& rWorkArea) |
116 | 0 | { |
117 | 0 | if(rWorkArea.IsEmpty()) |
118 | 0 | return; |
119 | | |
120 | 0 | ::tools::Rectangle aMarkRect(Point(rPos.X() - (rSize.Width() / 2), rPos.Y() - (rSize.Height() / 2)), rSize); |
121 | |
|
122 | 0 | if(aMarkRect.Contains(rWorkArea)) |
123 | 0 | return; |
124 | | |
125 | 0 | if(aMarkRect.Left() < rWorkArea.Left()) |
126 | 0 | { |
127 | 0 | rPos.AdjustX(rWorkArea.Left() - aMarkRect.Left() ); |
128 | 0 | } |
129 | |
|
130 | 0 | if(aMarkRect.Right() > rWorkArea.Right()) |
131 | 0 | { |
132 | 0 | rPos.AdjustX( -(aMarkRect.Right() - rWorkArea.Right()) ); |
133 | 0 | } |
134 | |
|
135 | 0 | if(aMarkRect.Top() < rWorkArea.Top()) |
136 | 0 | { |
137 | 0 | rPos.AdjustY(rWorkArea.Top() - aMarkRect.Top() ); |
138 | 0 | } |
139 | |
|
140 | 0 | if(aMarkRect.Bottom() > rWorkArea.Bottom()) |
141 | 0 | { |
142 | 0 | rPos.AdjustY( -(aMarkRect.Bottom() - rWorkArea.Bottom()) ); |
143 | 0 | } |
144 | 0 | } |
145 | | |
146 | | bool View::InsertMetaFile( const TransferableDataHelper& rDataHelper, const Point& rPos, ImageMap const * pImageMap, bool bOptimize ) |
147 | 0 | { |
148 | 0 | GDIMetaFile aMtf; |
149 | |
|
150 | 0 | if( !rDataHelper.GetGDIMetaFile( SotClipboardFormatId::GDIMETAFILE, aMtf ) ) |
151 | 0 | return false; |
152 | | |
153 | 0 | bool bVector = false; |
154 | 0 | Graphic aGraphic; |
155 | | |
156 | | // check if metafile only contains a pixel image, if so insert a bitmap instead |
157 | 0 | if( bOptimize ) |
158 | 0 | { |
159 | 0 | MetaAction* pAction = aMtf.FirstAction(); |
160 | 0 | while( pAction && !bVector ) |
161 | 0 | { |
162 | 0 | switch( pAction->GetType() ) |
163 | 0 | { |
164 | 0 | case MetaActionType::POINT: |
165 | 0 | case MetaActionType::LINE: |
166 | 0 | case MetaActionType::RECT: |
167 | 0 | case MetaActionType::ROUNDRECT: |
168 | 0 | case MetaActionType::ELLIPSE: |
169 | 0 | case MetaActionType::ARC: |
170 | 0 | case MetaActionType::PIE: |
171 | 0 | case MetaActionType::CHORD: |
172 | 0 | case MetaActionType::POLYLINE: |
173 | 0 | case MetaActionType::POLYGON: |
174 | 0 | case MetaActionType::POLYPOLYGON: |
175 | 0 | case MetaActionType::TEXT: |
176 | 0 | case MetaActionType::TEXTARRAY: |
177 | 0 | case MetaActionType::STRETCHTEXT: |
178 | 0 | case MetaActionType::TEXTRECT: |
179 | 0 | case MetaActionType::GRADIENT: |
180 | 0 | case MetaActionType::HATCH: |
181 | 0 | case MetaActionType::WALLPAPER: |
182 | 0 | case MetaActionType::EPS: |
183 | 0 | case MetaActionType::TEXTLINE: |
184 | 0 | case MetaActionType::FLOATTRANSPARENT: |
185 | 0 | case MetaActionType::GRADIENTEX: |
186 | 0 | case MetaActionType::BMPSCALEPART: |
187 | 0 | case MetaActionType::BMPEXSCALEPART: |
188 | 0 | bVector = true; |
189 | 0 | break; |
190 | 0 | case MetaActionType::BMP: |
191 | 0 | case MetaActionType::BMPSCALE: |
192 | 0 | case MetaActionType::BMPEX: |
193 | 0 | case MetaActionType::BMPEXSCALE: |
194 | 0 | if( aGraphic.GetType() != GraphicType::NONE ) |
195 | 0 | { |
196 | 0 | bVector = true; |
197 | 0 | } |
198 | 0 | else switch( pAction->GetType() ) |
199 | 0 | { |
200 | 0 | case MetaActionType::BMP: |
201 | 0 | { |
202 | 0 | MetaBmpAction* pBmpAction = dynamic_cast< MetaBmpAction* >( pAction ); |
203 | 0 | if( pBmpAction ) |
204 | 0 | aGraphic = Graphic(pBmpAction->GetBitmap()); |
205 | 0 | } |
206 | 0 | break; |
207 | 0 | case MetaActionType::BMPSCALE: |
208 | 0 | { |
209 | 0 | MetaBmpScaleAction* pBmpScaleAction = dynamic_cast< MetaBmpScaleAction* >( pAction ); |
210 | 0 | if( pBmpScaleAction ) |
211 | 0 | aGraphic = Graphic(pBmpScaleAction->GetBitmap()); |
212 | 0 | } |
213 | 0 | break; |
214 | 0 | case MetaActionType::BMPEX: |
215 | 0 | { |
216 | 0 | MetaBmpExAction* pBmpExAction = dynamic_cast< MetaBmpExAction* >( pAction ); |
217 | 0 | if( pBmpExAction ) |
218 | 0 | aGraphic = Graphic(pBmpExAction->GetBitmap()); |
219 | 0 | } |
220 | 0 | break; |
221 | 0 | case MetaActionType::BMPEXSCALE: |
222 | 0 | { |
223 | 0 | MetaBmpExScaleAction* pBmpExScaleAction = dynamic_cast< MetaBmpExScaleAction* >( pAction ); |
224 | 0 | if( pBmpExScaleAction ) |
225 | 0 | aGraphic = Graphic( pBmpExScaleAction->GetBitmap() ); |
226 | 0 | } |
227 | 0 | break; |
228 | 0 | default: break; |
229 | 0 | } |
230 | 0 | break; |
231 | 0 | default: break; |
232 | 0 | } |
233 | | |
234 | 0 | pAction = aMtf.NextAction(); |
235 | 0 | } |
236 | 0 | } |
237 | | |
238 | | // it is not a vector metafile but it also has no graphic? |
239 | 0 | if( !bVector && (aGraphic.GetType() == GraphicType::NONE) ) |
240 | 0 | bVector = true; |
241 | | |
242 | | // restrict movement to WorkArea |
243 | 0 | Point aInsertPos( rPos ); |
244 | 0 | Size aImageSize = bVector ? aMtf.GetPrefSize() : aGraphic.GetSizePixel(); |
245 | 0 | ImpCheckInsertPos(aInsertPos, aImageSize, GetWorkArea()); |
246 | |
|
247 | 0 | if( bVector ) |
248 | 0 | aGraphic = Graphic( aMtf ); |
249 | |
|
250 | 0 | aGraphic.SetPrefMapMode( aMtf.GetPrefMapMode() ); |
251 | 0 | aGraphic.SetPrefSize( aMtf.GetPrefSize() ); |
252 | 0 | InsertGraphic( aGraphic, mnAction, aInsertPos, nullptr, pImageMap ); |
253 | |
|
254 | 0 | return true; |
255 | 0 | } |
256 | | |
257 | | bool View::InsertData( const TransferableDataHelper& rDataHelper, |
258 | | const Point& rPos, sal_Int8& rDnDAction, bool bDrag, |
259 | | SotClipboardFormatId nFormat, sal_uInt16 nPage, SdrLayerID nLayer ) |
260 | 0 | { |
261 | 0 | maDropPos = rPos; |
262 | 0 | mnAction = rDnDAction; |
263 | 0 | mbIsDropAllowed = false; |
264 | |
|
265 | 0 | bool bLink = ( ( mnAction & DND_ACTION_LINK ) != 0 ); |
266 | 0 | bool bCopy = ( ( ( mnAction & DND_ACTION_COPY ) != 0 ) || bLink ); |
267 | 0 | SdrInsertFlags nPasteOptions = SdrInsertFlags::SETDEFLAYER; |
268 | |
|
269 | 0 | if (mpViewSh != nullptr) |
270 | 0 | { |
271 | 0 | OSL_ASSERT (mpViewSh->GetViewShell()!=nullptr); |
272 | 0 | SfxInPlaceClient* pIpClient = mpViewSh->GetViewShell()->GetIPClient(); |
273 | 0 | if( dynamic_cast< ::sd::slidesorter::SlideSorterViewShell *>( mpViewSh ) != nullptr |
274 | 0 | || (pIpClient!=nullptr && pIpClient->IsObjectInPlaceActive())) |
275 | 0 | nPasteOptions |= SdrInsertFlags::DONTMARK; |
276 | 0 | } |
277 | |
|
278 | 0 | SdrObject* pPickObj = nullptr; |
279 | 0 | if( bDrag ) |
280 | 0 | { |
281 | 0 | SdrPageView* pPV = nullptr; |
282 | 0 | pPickObj = PickObj(rPos, getHitTolLog(), pPV); |
283 | 0 | } |
284 | |
|
285 | 0 | SdPage* pPage = nullptr; |
286 | 0 | if( nPage != SDRPAGE_NOTFOUND ) |
287 | 0 | pPage = static_cast<SdPage*>( mrDoc.GetPage( nPage ) ); |
288 | |
|
289 | 0 | SdTransferable* pOwnData = nullptr; |
290 | 0 | SdTransferable* pImplementation = SdTransferable::getImplementation( rDataHelper.GetTransferable() ); |
291 | |
|
292 | 0 | if(pImplementation && (rDnDAction & DND_ACTION_LINK)) |
293 | 0 | { |
294 | | // suppress own data when it's intention is to use it as fill information |
295 | 0 | pImplementation = nullptr; |
296 | 0 | } |
297 | |
|
298 | 0 | bool bSelfDND = false; |
299 | | |
300 | | // try to get own transfer data |
301 | 0 | if( pImplementation ) |
302 | 0 | { |
303 | 0 | SdModule* mod = SdModule::get(); |
304 | 0 | if (mod->pTransferClip == pImplementation) |
305 | 0 | pOwnData = mod->pTransferClip; |
306 | 0 | else if (mod->pTransferDrag == pImplementation) |
307 | 0 | { |
308 | 0 | pOwnData = mod->pTransferDrag; |
309 | 0 | bSelfDND = true; |
310 | 0 | } |
311 | 0 | else if (mod->pTransferSelection == pImplementation) |
312 | 0 | pOwnData = mod->pTransferSelection; |
313 | 0 | } |
314 | |
|
315 | 0 | const bool bGroupUndoFromDragWithDrop = bSelfDND && mpDragSrcMarkList && IsUndoEnabled(); |
316 | 0 | if (bGroupUndoFromDragWithDrop) |
317 | 0 | { |
318 | 0 | OUString aStr(SdResId(STR_UNDO_DRAGDROP)); |
319 | 0 | BegUndo(aStr + " " + mpDragSrcMarkList->GetMarkDescription()); |
320 | 0 | } |
321 | | |
322 | | // ImageMap? |
323 | 0 | std::unique_ptr<ImageMap> pImageMap; |
324 | 0 | if (!pOwnData && rDataHelper.HasFormat(SotClipboardFormatId::SVIM)) |
325 | 0 | { |
326 | 0 | if (std::unique_ptr<SvStream> xStm = rDataHelper.GetSotStorageStream( SotClipboardFormatId::SVIM ) ) |
327 | 0 | { |
328 | 0 | pImageMap.reset(new ImageMap); |
329 | | // mba: clipboard always must contain absolute URLs (could be from alien source) |
330 | 0 | pImageMap->Read( *xStm ); |
331 | 0 | } |
332 | 0 | } |
333 | |
|
334 | 0 | bool bTable = false; |
335 | | // check special cases for pasting table formats as RTL |
336 | 0 | if( !bLink && (nFormat == SotClipboardFormatId::NONE || (nFormat == SotClipboardFormatId::RTF) || (nFormat == SotClipboardFormatId::RICHTEXT)) ) |
337 | 0 | { |
338 | | // if the object supports rtf and there is a table involved, default is to create a table |
339 | 0 | bool bIsRTF = rDataHelper.HasFormat(SotClipboardFormatId::RTF); |
340 | 0 | if( ( bIsRTF || rDataHelper.HasFormat( SotClipboardFormatId::RICHTEXT ) ) |
341 | 0 | && ! rDataHelper.HasFormat( SotClipboardFormatId::DRAWING ) ) |
342 | 0 | { |
343 | 0 | auto nFormatId = bIsRTF ? SotClipboardFormatId::RTF : SotClipboardFormatId::RICHTEXT; |
344 | 0 | if (std::unique_ptr<SvStream> xStm = rDataHelper.GetSotStorageStream(nFormatId)) |
345 | 0 | { |
346 | 0 | xStm->Seek( 0 ); |
347 | |
|
348 | 0 | OStringBuffer aLine; |
349 | 0 | while (xStm->ReadLine(aLine)) |
350 | 0 | { |
351 | 0 | size_t x = std::string_view(aLine).find( "\\trowd" ); |
352 | 0 | if (x != std::string_view::npos) |
353 | 0 | { |
354 | 0 | bTable = true; |
355 | 0 | nFormat = bIsRTF ? SotClipboardFormatId::RTF : SotClipboardFormatId::RICHTEXT; |
356 | 0 | break; |
357 | 0 | } |
358 | 0 | } |
359 | 0 | } |
360 | 0 | } |
361 | 0 | } |
362 | |
|
363 | 0 | comphelper::ScopeGuard cleanupGuard( |
364 | 0 | [this, &rDnDAction, bGroupUndoFromDragWithDrop] |
365 | 0 | { |
366 | 0 | MarkListHasChanged(); |
367 | 0 | mbIsDropAllowed = true; |
368 | 0 | rDnDAction = mnAction; |
369 | |
|
370 | 0 | if (bGroupUndoFromDragWithDrop) |
371 | 0 | { |
372 | | // this is called eventually by the underlying toolkit anyway in the case of a self-dnd |
373 | | // but we call it early in this case to group its undo actions into this open dnd undo group |
374 | | // and rely on that repeated calls to View::DragFinished are safe to do |
375 | 0 | DragFinished(mnAction); |
376 | 0 | EndUndo(); |
377 | 0 | } |
378 | 0 | }); |
379 | |
|
380 | 0 | auto ShouldTry = [nFormat, &rDataHelper](SotClipboardFormatId _def_Type) |
381 | 0 | { |
382 | 0 | return (nFormat == _def_Type || nFormat == SotClipboardFormatId::NONE) |
383 | 0 | && rDataHelper.HasFormat(_def_Type); |
384 | 0 | }; |
385 | |
|
386 | 0 | if (pOwnData) |
387 | 0 | { |
388 | | // Paste only if SfxClassificationHelper recommends so. |
389 | 0 | const SfxObjectShellRef& pSource = pOwnData->GetDocShell(); |
390 | 0 | SfxObjectShell* pDestination = mrDoc.GetDocSh(); |
391 | 0 | if (pSource.is() && pDestination) |
392 | 0 | { |
393 | 0 | SfxClassificationCheckPasteResult eResult = SfxClassificationHelper::CheckPaste(pSource->getDocProperties(), pDestination->getDocProperties()); |
394 | 0 | if (!SfxClassificationHelper::ShowPasteInfo(eResult)) |
395 | 0 | return true; |
396 | 0 | } |
397 | 0 | } |
398 | | |
399 | 0 | if (pOwnData && nFormat == SotClipboardFormatId::NONE) |
400 | 0 | { |
401 | 0 | const View* pSourceView = pOwnData->GetView(); |
402 | |
|
403 | 0 | if( pOwnData->GetDocShell().is() && pOwnData->IsPageTransferable() ) |
404 | 0 | { |
405 | 0 | mpClipboard->HandlePageDrop (*pOwnData); |
406 | 0 | return true; |
407 | 0 | } |
408 | 0 | else if( pSourceView ) |
409 | 0 | { |
410 | 0 | if( pSourceView == this ) |
411 | 0 | { |
412 | | // same view |
413 | 0 | if( nLayer != SDRLAYER_NOTFOUND ) |
414 | 0 | { |
415 | | // drop on layer tab bar |
416 | 0 | SdrLayerAdmin& rLayerAdmin = mrDoc.GetLayerAdmin(); |
417 | 0 | SdrLayer* pLayer = rLayerAdmin.GetLayerPerID( nLayer ); |
418 | 0 | SdrPageView* pPV = GetSdrPageView(); |
419 | 0 | OUString aLayer = pLayer->GetName(); |
420 | |
|
421 | 0 | if( !pPV->IsLayerLocked( aLayer ) ) |
422 | 0 | { |
423 | 0 | pOwnData->SetInternalMove( true ); |
424 | 0 | const SdrMarkList& rMarkList = GetMarkedObjectList(); |
425 | 0 | rMarkList.ForceSort(); |
426 | |
|
427 | 0 | for( size_t nM = 0; nM < rMarkList.GetMarkCount(); ++nM ) |
428 | 0 | { |
429 | 0 | SdrMark* pM = rMarkList.GetMark( nM ); |
430 | 0 | SdrObject* pO = pM->GetMarkedSdrObj(); |
431 | |
|
432 | 0 | if( pO ) |
433 | 0 | { |
434 | | // #i11702# |
435 | 0 | if( IsUndoEnabled() ) |
436 | 0 | { |
437 | 0 | BegUndo(SdResId(STR_MODIFYLAYER)); |
438 | 0 | AddUndo(GetModel().GetSdrUndoFactory().CreateUndoObjectLayerChange(*pO, pO->GetLayer(), nLayer)); |
439 | 0 | EndUndo(); |
440 | 0 | } |
441 | |
|
442 | 0 | pO->SetLayer( nLayer ); |
443 | 0 | } |
444 | 0 | } |
445 | |
|
446 | 0 | return true; |
447 | 0 | } |
448 | 0 | } |
449 | 0 | else |
450 | 0 | { |
451 | 0 | SdrPageView* pPV = GetSdrPageView(); |
452 | 0 | bool bDropOnTabBar = true; |
453 | |
|
454 | 0 | if( !pPage && pPV->GetPage()->GetPageNum() != mnDragSrcPgNum ) |
455 | 0 | { |
456 | 0 | pPage = static_cast<SdPage*>( pPV->GetPage() ); |
457 | 0 | bDropOnTabBar = false; |
458 | 0 | } |
459 | |
|
460 | 0 | if( pPage ) |
461 | 0 | { |
462 | | // drop on other page |
463 | 0 | OUString aActiveLayer = GetActiveLayer(); |
464 | |
|
465 | 0 | if( !pPV->IsLayerLocked( aActiveLayer ) ) |
466 | 0 | { |
467 | 0 | if( !IsPresObjSelected() ) |
468 | 0 | { |
469 | 0 | SdrMarkList* pMarkList; |
470 | |
|
471 | 0 | if( (mnDragSrcPgNum != SDRPAGE_NOTFOUND) && (mnDragSrcPgNum != pPV->GetPage()->GetPageNum()) ) |
472 | 0 | { |
473 | 0 | pMarkList = mpDragSrcMarkList.get(); |
474 | 0 | } |
475 | 0 | else |
476 | 0 | { |
477 | | // actual mark list is used |
478 | 0 | pMarkList = new SdrMarkList( GetMarkedObjectList()); |
479 | 0 | } |
480 | |
|
481 | 0 | pMarkList->ForceSort(); |
482 | | |
483 | | // stuff to remember originals and clones |
484 | 0 | std::vector<ImpRememberOrigAndClone> aConnectorContainer; |
485 | 0 | size_t nConnectorCount = 0; |
486 | 0 | Point aCurPos; |
487 | | |
488 | | // calculate real position of current |
489 | | // source objects, if necessary (#103207) |
490 | 0 | if (pOwnData == SdModule::get()->pTransferSelection) |
491 | 0 | { |
492 | 0 | ::tools::Rectangle aCurBoundRect; |
493 | |
|
494 | 0 | if( pMarkList->TakeBoundRect( pPV, aCurBoundRect ) ) |
495 | 0 | aCurPos = aCurBoundRect.TopLeft(); |
496 | 0 | else |
497 | 0 | aCurPos = pOwnData->GetStartPos(); |
498 | 0 | } |
499 | 0 | else |
500 | 0 | aCurPos = pOwnData->GetStartPos(); |
501 | |
|
502 | 0 | const Size aVector( maDropPos.X() - aCurPos.X(), maDropPos.Y() - aCurPos.Y() ); |
503 | |
|
504 | 0 | std::unordered_set<rtl::OUString> aNameSet; |
505 | 0 | for(size_t a = 0; a < pMarkList->GetMarkCount(); ++a) |
506 | 0 | { |
507 | 0 | SdrMark* pM = pMarkList->GetMark(a); |
508 | 0 | rtl::Reference<SdrObject> pObj(pM->GetMarkedSdrObj()->CloneSdrObject(pPage->getSdrModelFromSdrPage())); |
509 | |
|
510 | 0 | if(pObj) |
511 | 0 | { |
512 | 0 | if(!bDropOnTabBar) |
513 | 0 | { |
514 | | // do a NbcMove(...) instead of setting SnapRects here |
515 | 0 | pObj->NbcMove(aVector); |
516 | 0 | } |
517 | |
|
518 | 0 | SdrObject* pMarkParent = pM->GetMarkedSdrObj()->getParentSdrObjectFromSdrObject(); |
519 | 0 | if (bCopy || (pMarkParent && pMarkParent->IsGroupObject())) |
520 | 0 | pPage->InsertObjectThenMakeNameUnique(pObj.get(), aNameSet); |
521 | 0 | else |
522 | 0 | pPage->InsertObject(pObj.get()); |
523 | |
|
524 | 0 | if( IsUndoEnabled() ) |
525 | 0 | { |
526 | 0 | BegUndo(SdResId(STR_UNDO_DRAGDROP)); |
527 | 0 | AddUndo(GetModel().GetSdrUndoFactory().CreateUndoNewObject(*pObj)); |
528 | 0 | EndUndo(); |
529 | 0 | } |
530 | |
|
531 | 0 | ImpRememberOrigAndClone aRem; |
532 | 0 | aRem.pOrig = pM->GetMarkedSdrObj(); |
533 | 0 | aRem.pClone = pObj.get(); |
534 | 0 | aConnectorContainer.push_back(aRem); |
535 | |
|
536 | 0 | if(dynamic_cast< SdrEdgeObj *>( pObj.get() ) != nullptr) |
537 | 0 | nConnectorCount++; |
538 | 0 | } |
539 | 0 | } |
540 | | |
541 | | // try to re-establish connections at clones |
542 | 0 | if(nConnectorCount) |
543 | 0 | { |
544 | 0 | for(size_t a = 0; a < aConnectorContainer.size(); ++a) |
545 | 0 | { |
546 | 0 | ImpRememberOrigAndClone* pRem = &aConnectorContainer[a]; |
547 | |
|
548 | 0 | if(auto pCloneEdge = dynamic_cast<SdrEdgeObj *>( pRem->pClone )) |
549 | 0 | { |
550 | 0 | SdrEdgeObj* pOrigEdge = static_cast<SdrEdgeObj*>(pRem->pOrig); |
551 | | |
552 | | // test first connection |
553 | 0 | SdrObjConnection& rConn0 = pOrigEdge->GetConnection(false); |
554 | 0 | SdrObject* pConnObj = rConn0.GetSdrObject(); |
555 | 0 | if(pConnObj) |
556 | 0 | { |
557 | 0 | SdrObject* pConnClone = ImpGetClone(aConnectorContainer, pConnObj); |
558 | 0 | if(pConnClone) |
559 | 0 | { |
560 | | // if dest obj was cloned, too, re-establish connection |
561 | 0 | pCloneEdge->ConnectToNode(false, pConnClone); |
562 | 0 | pCloneEdge->GetConnection(false).SetConnectorId(rConn0.GetConnectorId()); |
563 | 0 | } |
564 | 0 | else |
565 | 0 | { |
566 | | // set position of connection point of original connected object |
567 | 0 | const SdrGluePointList* pGlueList = pConnObj->GetGluePointList(); |
568 | 0 | if(pGlueList) |
569 | 0 | { |
570 | 0 | sal_uInt16 nInd = pGlueList->FindGluePoint(rConn0.GetConnectorId()); |
571 | |
|
572 | 0 | if(SDRGLUEPOINT_NOTFOUND != nInd) |
573 | 0 | { |
574 | 0 | const SdrGluePoint& rGluePoint = (*pGlueList)[nInd]; |
575 | 0 | Point aPosition = rGluePoint.GetAbsolutePos(*pConnObj); |
576 | 0 | aPosition.AdjustX(aVector.Width() ); |
577 | 0 | aPosition.AdjustY(aVector.Height() ); |
578 | 0 | pCloneEdge->SetTailPoint(false, aPosition); |
579 | 0 | } |
580 | 0 | } |
581 | 0 | } |
582 | 0 | } |
583 | | |
584 | | // test second connection |
585 | 0 | SdrObjConnection& rConn1 = pOrigEdge->GetConnection(true); |
586 | 0 | pConnObj = rConn1.GetSdrObject(); |
587 | 0 | if(pConnObj) |
588 | 0 | { |
589 | 0 | SdrObject* pConnClone = ImpGetClone(aConnectorContainer, pConnObj); |
590 | 0 | if(pConnClone) |
591 | 0 | { |
592 | | // if dest obj was cloned, too, re-establish connection |
593 | 0 | pCloneEdge->ConnectToNode(true, pConnClone); |
594 | 0 | pCloneEdge->GetConnection(true).SetConnectorId(rConn1.GetConnectorId()); |
595 | 0 | } |
596 | 0 | else |
597 | 0 | { |
598 | | // set position of connection point of original connected object |
599 | 0 | const SdrGluePointList* pGlueList = pConnObj->GetGluePointList(); |
600 | 0 | if(pGlueList) |
601 | 0 | { |
602 | 0 | sal_uInt16 nInd = pGlueList->FindGluePoint(rConn1.GetConnectorId()); |
603 | |
|
604 | 0 | if(SDRGLUEPOINT_NOTFOUND != nInd) |
605 | 0 | { |
606 | 0 | const SdrGluePoint& rGluePoint = (*pGlueList)[nInd]; |
607 | 0 | Point aPosition = rGluePoint.GetAbsolutePos(*pConnObj); |
608 | 0 | aPosition.AdjustX(aVector.Width() ); |
609 | 0 | aPosition.AdjustY(aVector.Height() ); |
610 | 0 | pCloneEdge->SetTailPoint(true, aPosition); |
611 | 0 | } |
612 | 0 | } |
613 | 0 | } |
614 | 0 | } |
615 | 0 | } |
616 | 0 | } |
617 | 0 | } |
618 | |
|
619 | 0 | if( pMarkList != mpDragSrcMarkList.get() ) |
620 | 0 | delete pMarkList; |
621 | |
|
622 | 0 | return true; |
623 | 0 | } |
624 | 0 | else |
625 | 0 | { |
626 | 0 | maDropErrorIdle.Start(); |
627 | 0 | } |
628 | 0 | } |
629 | 0 | } |
630 | 0 | else |
631 | 0 | { |
632 | 0 | pOwnData->SetInternalMove( true ); |
633 | 0 | MoveAllMarked( Size( maDropPos.X() - pOwnData->GetStartPos().X(), |
634 | 0 | maDropPos.Y() - pOwnData->GetStartPos().Y() ), bCopy ); |
635 | 0 | return true; |
636 | 0 | } |
637 | 0 | } |
638 | 0 | } |
639 | 0 | else |
640 | 0 | { |
641 | | // different views |
642 | 0 | if( !pSourceView->IsPresObjSelected() ) |
643 | 0 | { |
644 | | // model is owned by from AllocModel() created DocShell |
645 | 0 | SdDrawDocument* pSourceDoc = static_cast<SdDrawDocument*>(&pSourceView->GetModel()); |
646 | 0 | pSourceDoc->CreatingDataObj( pOwnData ); |
647 | 0 | SdDrawDocument* pModel = static_cast<SdDrawDocument*>( pSourceView->CreateMarkedObjModel().release() ); |
648 | 0 | bool bReturn = Paste(*pModel, maDropPos, pPage, nPasteOptions); |
649 | |
|
650 | 0 | if( !pPage ) |
651 | 0 | pPage = static_cast<SdPage*>( GetSdrPageView()->GetPage() ); |
652 | |
|
653 | 0 | OUString aLayout = pPage->GetLayoutName(); |
654 | 0 | sal_Int32 nPos = aLayout.indexOf(SD_LT_SEPARATOR); |
655 | 0 | if (nPos != -1) |
656 | 0 | aLayout = aLayout.copy(0, nPos); |
657 | 0 | pPage->SetPresentationLayout( aLayout, false, false ); |
658 | 0 | pSourceDoc->CreatingDataObj( nullptr ); |
659 | 0 | if (bReturn) |
660 | 0 | return true; |
661 | 0 | } |
662 | 0 | else |
663 | 0 | { |
664 | 0 | maDropErrorIdle.Start(); |
665 | 0 | } |
666 | 0 | } |
667 | 0 | } |
668 | 0 | else |
669 | 0 | { |
670 | 0 | SdDrawDocument* pWorkModel = const_cast<SdDrawDocument*>(pOwnData->GetWorkDocument()); |
671 | 0 | SdPage* pWorkPage = pWorkModel->GetSdPage( 0, PageKind::Standard ); |
672 | |
|
673 | 0 | pWorkPage->SetSdrObjListRectsDirty(); |
674 | | |
675 | | // tdf#118171 - snap rectangles of objects without line width |
676 | 0 | const Size aSize(pWorkPage->GetAllObjSnapRect().GetSize()); |
677 | |
|
678 | 0 | maDropPos.setX( pOwnData->GetBoundStartPos().X() + ( aSize.Width() >> 1 ) ); |
679 | 0 | maDropPos.setY( pOwnData->GetBoundStartPos().Y() + ( aSize.Height() >> 1 ) ); |
680 | | |
681 | | // delete pages, that are not of any interest for us |
682 | 0 | for( ::tools::Long i = pWorkModel->GetPageCount() - 1; i >= 0; i-- ) |
683 | 0 | { |
684 | 0 | SdPage* pP = static_cast< SdPage* >( pWorkModel->GetPage( static_cast<sal_uInt16>(i) ) ); |
685 | |
|
686 | 0 | if( pP->GetPageKind() != PageKind::Standard ) |
687 | 0 | pWorkModel->DeletePage( static_cast<sal_uInt16>(i) ); |
688 | 0 | } |
689 | |
|
690 | 0 | bool bReturn = Paste(*pWorkModel, maDropPos, pPage, nPasteOptions); |
691 | |
|
692 | 0 | if( !pPage ) |
693 | 0 | pPage = static_cast<SdPage*>( GetSdrPageView()->GetPage() ); |
694 | |
|
695 | 0 | OUString aLayout = pPage->GetLayoutName(); |
696 | 0 | sal_Int32 nPos = aLayout.indexOf(SD_LT_SEPARATOR); |
697 | 0 | if (nPos != -1) |
698 | 0 | aLayout = aLayout.copy(0, nPos); |
699 | 0 | pPage->SetPresentationLayout( aLayout, false, false ); |
700 | 0 | if (bReturn) |
701 | 0 | return true; |
702 | 0 | } |
703 | 0 | } |
704 | | |
705 | 0 | if (ShouldTry(SotClipboardFormatId::PDF)) |
706 | 0 | { |
707 | 0 | if (std::unique_ptr<SvStream> xStm = rDataHelper.GetSotStorageStream( SotClipboardFormatId::PDF )) |
708 | 0 | { |
709 | 0 | Point aInsertPos(rPos); |
710 | 0 | Graphic aGraphic; |
711 | 0 | if (vcl::ImportPDF(*xStm, aGraphic)) |
712 | 0 | { |
713 | 0 | const sal_uInt64 nGraphicContentSize(xStm->Tell()); |
714 | 0 | xStm->Seek(0); |
715 | 0 | BinaryDataContainer aGraphicContent(*xStm, nGraphicContentSize); |
716 | 0 | aGraphic.SetGfxLink(std::make_shared<GfxLink>(aGraphicContent, GfxLinkType::NativePdf)); |
717 | |
|
718 | 0 | InsertGraphic(aGraphic, mnAction, aInsertPos, nullptr, nullptr); |
719 | 0 | return true; |
720 | 0 | } |
721 | 0 | } |
722 | 0 | } |
723 | | |
724 | 0 | if (ShouldTry(SotClipboardFormatId::EMBED_SOURCE)) |
725 | 0 | { |
726 | 0 | if (::sd::slidesorter::SlideSorterViewShell* pSlideSorterViewShell = |
727 | 0 | ::sd::slidesorter::SlideSorterViewShell::GetSlideSorter( |
728 | 0 | mrDoc.GetDocSh()->GetViewShell()->GetViewShellBase())) |
729 | 0 | { |
730 | 0 | if (pSlideSorterViewShell->GetSlideSorter().GetController().GetClipboard().PasteSlidesFromSystemClipboard()) |
731 | 0 | return true; |
732 | 0 | } |
733 | 0 | } |
734 | | |
735 | 0 | if (ShouldTry(SotClipboardFormatId::DRAWING)) |
736 | 0 | { |
737 | 0 | if (std::unique_ptr<SvStream> xStm = rDataHelper.GetSotStorageStream( SotClipboardFormatId::DRAWING )) |
738 | 0 | { |
739 | 0 | DrawDocShellRef xShell = new DrawDocShell(SfxObjectCreateMode::INTERNAL, false, DocumentType::Impress); |
740 | 0 | xShell->DoInitNew(); |
741 | |
|
742 | 0 | SdDrawDocument* pModel = xShell->GetDoc(); |
743 | 0 | pModel->InsertPage(pModel->AllocPage(false).get()); |
744 | |
|
745 | 0 | Reference< XComponent > xComponent = xShell->GetModel(); |
746 | 0 | xStm->Seek( 0 ); |
747 | |
|
748 | 0 | css::uno::Reference< css::io::XInputStream > xInputStream( new utl::OInputStreamWrapper( *xStm ) ); |
749 | 0 | bool bReturn = SvxDrawingLayerImport( pModel, xInputStream, xComponent, "com.sun.star.comp.Impress.XMLOasisImporter" ); |
750 | |
|
751 | 0 | if( pModel->GetPageCount() == 0 ) |
752 | 0 | { |
753 | 0 | OSL_FAIL("empty or invalid drawing xml document on clipboard!" ); |
754 | 0 | } |
755 | 0 | else |
756 | 0 | { |
757 | 0 | bool bChanged = false; |
758 | |
|
759 | 0 | if (bReturn && (mnAction & (DND_ACTION_MOVE | DND_ACTION_LINK))) |
760 | 0 | { |
761 | 0 | if( pModel->GetSdPage( 0, PageKind::Standard )->GetObjCount() == 1 ) |
762 | 0 | { |
763 | | // only one object |
764 | 0 | SdrObject* pObj = pModel->GetSdPage( 0, PageKind::Standard )->GetObj( 0 ); |
765 | 0 | SdrPageView* pPV = nullptr; |
766 | 0 | SdrObject* pPickObj2 = PickObj(rPos, getHitTolLog(), pPV); |
767 | |
|
768 | 0 | if( ( mnAction & DND_ACTION_MOVE ) && pPickObj2 && pObj ) |
769 | 0 | { |
770 | | // replace object |
771 | 0 | SdrPage* pWorkPage = GetSdrPageView()->GetPage(); |
772 | 0 | rtl::Reference<SdrObject> pNewObj(pObj->CloneSdrObject(pWorkPage->getSdrModelFromSdrPage())); |
773 | 0 | ::tools::Rectangle aPickObjRect( pPickObj2->GetCurrentBoundRect() ); |
774 | 0 | Size aPickObjSize( aPickObjRect.GetSize() ); |
775 | 0 | Point aVec( aPickObjRect.TopLeft() ); |
776 | 0 | ::tools::Rectangle aObjRect( pNewObj->GetCurrentBoundRect() ); |
777 | 0 | Size aObjSize( aObjRect.GetSize() ); |
778 | |
|
779 | 0 | double aScaleWidth = double( aPickObjSize.Width() ) / aObjSize.Width(); |
780 | 0 | double aScaleHeight = double( aPickObjSize.Height() ) / aObjSize.Height(); |
781 | 0 | pNewObj->NbcResize( aObjRect.TopLeft(), aScaleWidth, aScaleHeight ); |
782 | |
|
783 | 0 | aVec -= aObjRect.TopLeft(); |
784 | 0 | pNewObj->NbcMove( Size( aVec.X(), aVec.Y() ) ); |
785 | |
|
786 | 0 | const bool bUndo = IsUndoEnabled(); |
787 | |
|
788 | 0 | if( bUndo ) |
789 | 0 | BegUndo(SdResId(STR_UNDO_DRAGDROP)); |
790 | 0 | pNewObj->NbcSetLayer( pPickObj2->GetLayer() ); |
791 | 0 | pWorkPage->InsertObject( pNewObj.get() ); |
792 | 0 | if( bUndo ) |
793 | 0 | { |
794 | 0 | AddUndo( mrDoc.GetSdrUndoFactory().CreateUndoNewObject( *pNewObj ) ); |
795 | 0 | AddUndo( mrDoc.GetSdrUndoFactory().CreateUndoDeleteObject( *pPickObj2 ) ); |
796 | 0 | } |
797 | 0 | pWorkPage->RemoveObject( pPickObj2->GetOrdNum() ); |
798 | |
|
799 | 0 | if( bUndo ) |
800 | 0 | { |
801 | 0 | EndUndo(); |
802 | 0 | } |
803 | |
|
804 | 0 | bChanged = true; |
805 | 0 | mnAction = DND_ACTION_COPY; |
806 | 0 | } |
807 | 0 | else if( ( mnAction & DND_ACTION_LINK ) && pPickObj2 && pObj && |
808 | 0 | dynamic_cast< const SdrGrafObj *>( pPickObj2 ) == nullptr && |
809 | 0 | dynamic_cast< const SdrOle2Obj *>( pPickObj2 ) == nullptr ) |
810 | 0 | { |
811 | 0 | SfxItemSet aSet( mrDoc.GetPool() ); |
812 | | |
813 | | // set new attributes to object |
814 | 0 | const bool bUndo = IsUndoEnabled(); |
815 | 0 | if( bUndo ) |
816 | 0 | { |
817 | 0 | BegUndo( SdResId(STR_UNDO_DRAGDROP) ); |
818 | 0 | AddUndo( mrDoc.GetSdrUndoFactory().CreateUndoAttrObject( *pPickObj2 ) ); |
819 | 0 | } |
820 | |
|
821 | 0 | aSet.Put( pObj->GetMergedItemSet() ); |
822 | | |
823 | | /* Do not take over corner radius. There are |
824 | | gradients (rectangles) in the gallery with corner |
825 | | radius of 0. We should not use that on the |
826 | | object. */ |
827 | 0 | aSet.ClearItem( SDRATTR_CORNER_RADIUS ); |
828 | |
|
829 | 0 | const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pObj); |
830 | |
|
831 | 0 | if(pSdrGrafObj) |
832 | 0 | { |
833 | | // If we have a graphic as source object, use its graphic |
834 | | // content as fill style |
835 | 0 | aSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP)); |
836 | 0 | aSet.Put(XFillBitmapItem(pSdrGrafObj->GetGraphic())); |
837 | 0 | } |
838 | |
|
839 | 0 | pPickObj2->SetMergedItemSetAndBroadcast( aSet ); |
840 | |
|
841 | 0 | if( DynCastE3dObject( pPickObj2 ) && DynCastE3dObject( pObj ) ) |
842 | 0 | { |
843 | | // handle 3D attribute in addition |
844 | 0 | SfxItemSet aNewSet(SfxItemSet::makeFixedSfxItemSet<SID_ATTR_3D_START, SID_ATTR_3D_END>( mrDoc.GetPool() )); |
845 | 0 | SfxItemSet aOldSet(SfxItemSet::makeFixedSfxItemSet<SID_ATTR_3D_START, SID_ATTR_3D_END>( mrDoc.GetPool() )); |
846 | |
|
847 | 0 | aOldSet.Put(pPickObj2->GetMergedItemSet()); |
848 | 0 | aNewSet.Put( pObj->GetMergedItemSet() ); |
849 | |
|
850 | 0 | if( bUndo ) |
851 | 0 | AddUndo( |
852 | 0 | std::make_unique<E3dAttributesUndoAction>( |
853 | 0 | *static_cast< E3dObject* >(pPickObj2), |
854 | 0 | aNewSet, |
855 | 0 | aOldSet)); |
856 | 0 | pPickObj2->SetMergedItemSetAndBroadcast( aNewSet ); |
857 | 0 | } |
858 | |
|
859 | 0 | if( bUndo ) |
860 | 0 | EndUndo(); |
861 | 0 | bChanged = true; |
862 | 0 | } |
863 | 0 | } |
864 | 0 | } |
865 | |
|
866 | 0 | if( !bChanged ) |
867 | 0 | { |
868 | 0 | SdrPage* pWorkPage = pModel->GetSdPage( 0, PageKind::Standard ); |
869 | |
|
870 | 0 | pWorkPage->SetSdrObjListRectsDirty(); |
871 | |
|
872 | 0 | if( pOwnData ) |
873 | 0 | { |
874 | | // tdf#118171 - snap rectangles of objects without line width |
875 | 0 | const Size aSize(pWorkPage->GetAllObjSnapRect().GetSize()); |
876 | |
|
877 | 0 | maDropPos.setX( pOwnData->GetBoundStartPos().X() + ( aSize.Width() >> 1 ) ); |
878 | 0 | maDropPos.setY( pOwnData->GetBoundStartPos().Y() + ( aSize.Height() >> 1 ) ); |
879 | 0 | } |
880 | |
|
881 | 0 | bReturn = Paste(*pModel, maDropPos, pPage, nPasteOptions); |
882 | 0 | } |
883 | |
|
884 | 0 | xShell->DoClose(); |
885 | 0 | } |
886 | 0 | if (bReturn) |
887 | 0 | return true; |
888 | 0 | } |
889 | 0 | } |
890 | | |
891 | 0 | if (ShouldTry(SotClipboardFormatId::SBA_FIELDDATAEXCHANGE)) |
892 | 0 | { |
893 | 0 | OUString aOUString; |
894 | |
|
895 | 0 | if (rDataHelper.GetString(SotClipboardFormatId::SBA_FIELDDATAEXCHANGE, aOUString)) |
896 | 0 | { |
897 | 0 | rtl::Reference<SdrObject> pObj = CreateFieldControl( aOUString ); |
898 | |
|
899 | 0 | if( pObj ) |
900 | 0 | { |
901 | 0 | ::tools::Rectangle aRect( pObj->GetLogicRect() ); |
902 | 0 | Size aSize( aRect.GetSize() ); |
903 | |
|
904 | 0 | maDropPos.AdjustX( -( aSize.Width() >> 1 ) ); |
905 | 0 | maDropPos.AdjustY( -( aSize.Height() >> 1 ) ); |
906 | |
|
907 | 0 | aRect.SetPos( maDropPos ); |
908 | 0 | pObj->SetLogicRect( aRect ); |
909 | 0 | InsertObjectAtView( pObj.get(), *GetSdrPageView(), SdrInsertFlags::SETDEFLAYER ); |
910 | 0 | return true; |
911 | 0 | } |
912 | 0 | } |
913 | 0 | } |
914 | | |
915 | 0 | if (!bLink && |
916 | 0 | (ShouldTry(SotClipboardFormatId::EMBED_SOURCE) || ShouldTry(SotClipboardFormatId::EMBEDDED_OBJ)) && |
917 | 0 | rDataHelper.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR)) |
918 | 0 | { |
919 | | //TODO/LATER: is it possible that this format is binary?! (from old versions of SO) |
920 | 0 | uno::Reference < io::XInputStream > xStm; |
921 | 0 | TransferableObjectDescriptor aObjDesc; |
922 | |
|
923 | 0 | if (rDataHelper.GetTransferableObjectDescriptor(SotClipboardFormatId::OBJECTDESCRIPTOR, aObjDesc)) |
924 | 0 | { |
925 | 0 | OUString aDocShellID = SfxObjectShell::CreateShellID(mrDoc.GetDocSh()); |
926 | 0 | xStm = rDataHelper.GetInputStream(nFormat != SotClipboardFormatId::NONE ? nFormat : SotClipboardFormatId::EMBED_SOURCE, aDocShellID); |
927 | 0 | if (!xStm.is()) |
928 | 0 | xStm = rDataHelper.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ, aDocShellID); |
929 | 0 | } |
930 | |
|
931 | 0 | if (xStm.is()) |
932 | 0 | { |
933 | 0 | if( mrDoc.GetDocSh() && ( mrDoc.GetDocSh()->GetClassName() == aObjDesc.maClassName ) ) |
934 | 0 | { |
935 | 0 | bool bReturn = false; |
936 | 0 | uno::Reference < embed::XStorage > xStore( ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm ) ); |
937 | 0 | ::sd::DrawDocShellRef xDocShRef( new ::sd::DrawDocShell( SfxObjectCreateMode::EMBEDDED, true, mrDoc.GetDocumentType() ) ); |
938 | | |
939 | | // mba: BaseURL doesn't make sense for clipboard functionality |
940 | 0 | SfxMedium *pMedium = new SfxMedium( xStore, OUString() ); |
941 | 0 | if( xDocShRef->DoLoad( pMedium ) ) |
942 | 0 | { |
943 | 0 | SdDrawDocument* pModel = xDocShRef->GetDoc(); |
944 | 0 | SdPage* pWorkPage = pModel->GetSdPage( 0, PageKind::Standard ); |
945 | |
|
946 | 0 | pWorkPage->SetSdrObjListRectsDirty(); |
947 | |
|
948 | 0 | if( pOwnData ) |
949 | 0 | { |
950 | | // tdf#118171 - snap rectangles of objects without line width |
951 | 0 | const Size aSize(pWorkPage->GetAllObjSnapRect().GetSize()); |
952 | |
|
953 | 0 | maDropPos.setX( pOwnData->GetBoundStartPos().X() + ( aSize.Width() >> 1 ) ); |
954 | 0 | maDropPos.setY( pOwnData->GetBoundStartPos().Y() + ( aSize.Height() >> 1 ) ); |
955 | 0 | } |
956 | | |
957 | | // delete pages, that are not of any interest for us |
958 | 0 | for( ::tools::Long i = pModel->GetPageCount() - 1; i >= 0; i-- ) |
959 | 0 | { |
960 | 0 | SdPage* pP = static_cast< SdPage* >( pModel->GetPage( static_cast<sal_uInt16>(i) ) ); |
961 | |
|
962 | 0 | if( pP->GetPageKind() != PageKind::Standard ) |
963 | 0 | pModel->DeletePage( static_cast<sal_uInt16>(i) ); |
964 | 0 | } |
965 | |
|
966 | 0 | bReturn = Paste(*pModel, maDropPos, pPage, nPasteOptions); |
967 | |
|
968 | 0 | if( !pPage ) |
969 | 0 | pPage = static_cast<SdPage*>(GetSdrPageView()->GetPage()); |
970 | |
|
971 | 0 | OUString aLayout = pPage->GetLayoutName(); |
972 | 0 | sal_Int32 nPos = aLayout.indexOf(SD_LT_SEPARATOR); |
973 | 0 | if (nPos != -1) |
974 | 0 | aLayout = aLayout.copy(0, nPos); |
975 | 0 | pPage->SetPresentationLayout( aLayout, false, false ); |
976 | 0 | } |
977 | |
|
978 | 0 | xDocShRef->DoClose(); |
979 | 0 | xDocShRef.clear(); |
980 | 0 | if (bReturn) |
981 | 0 | return true; |
982 | 0 | } |
983 | 0 | else |
984 | 0 | { |
985 | 0 | OUString aName; |
986 | 0 | uno::Reference < embed::XEmbeddedObject > xObj = mpDocSh->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName ); |
987 | 0 | if ( xObj.is() ) |
988 | 0 | { |
989 | 0 | svt::EmbeddedObjectRef aObjRef( xObj, aObjDesc.mnViewAspect ); |
990 | |
|
991 | 0 | Size aSize; |
992 | 0 | if ( aObjDesc.mnViewAspect == embed::Aspects::MSOLE_ICON ) |
993 | 0 | { |
994 | 0 | if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() ) |
995 | 0 | aSize = aObjDesc.maSize; |
996 | 0 | else |
997 | 0 | { |
998 | 0 | MapMode aMapMode( MapUnit::Map100thMM ); |
999 | 0 | aSize = aObjRef.GetSize( &aMapMode ); |
1000 | 0 | } |
1001 | 0 | } |
1002 | 0 | else |
1003 | 0 | { |
1004 | 0 | awt::Size aSz; |
1005 | 0 | MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( aObjDesc.mnViewAspect ) ); |
1006 | 0 | if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() ) |
1007 | 0 | { |
1008 | 0 | Size aTmp(OutputDevice::LogicToLogic(aObjDesc.maSize, MapMode(MapUnit::Map100thMM), MapMode(aMapUnit))); |
1009 | 0 | aSz.Width = aTmp.Width(); |
1010 | 0 | aSz.Height = aTmp.Height(); |
1011 | 0 | xObj->setVisualAreaSize( aObjDesc.mnViewAspect, aSz ); |
1012 | 0 | } |
1013 | |
|
1014 | 0 | try |
1015 | 0 | { |
1016 | 0 | aSz = xObj->getVisualAreaSize( aObjDesc.mnViewAspect ); |
1017 | 0 | } |
1018 | 0 | catch( embed::NoVisualAreaSizeException& ) |
1019 | 0 | { |
1020 | | // if the size still was not set the default size will be set later |
1021 | 0 | } |
1022 | |
|
1023 | 0 | aSize = Size( aSz.Width, aSz.Height ); |
1024 | |
|
1025 | 0 | if( !aSize.Width() || !aSize.Height() ) |
1026 | 0 | { |
1027 | 0 | aSize.setWidth( 14100 ); |
1028 | 0 | aSize.setHeight( 10000 ); |
1029 | 0 | aSize = OutputDevice::LogicToLogic(Size(14100, 10000), MapMode(MapUnit::Map100thMM), MapMode(aMapUnit)); |
1030 | 0 | aSz.Width = aSize.Width(); |
1031 | 0 | aSz.Height = aSize.Height(); |
1032 | 0 | xObj->setVisualAreaSize( aObjDesc.mnViewAspect, aSz ); |
1033 | 0 | } |
1034 | |
|
1035 | 0 | aSize = OutputDevice::LogicToLogic(aSize, MapMode(aMapUnit), MapMode(MapUnit::Map100thMM)); |
1036 | 0 | } |
1037 | |
|
1038 | 0 | Size aMaxSize( mrDoc.GetMaxObjSize() ); |
1039 | |
|
1040 | 0 | maDropPos.AdjustX( -(std::min( aSize.Width(), aMaxSize.Width() ) >> 1) ); |
1041 | 0 | maDropPos.AdjustY( -(std::min( aSize.Height(), aMaxSize.Height() ) >> 1) ); |
1042 | |
|
1043 | 0 | ::tools::Rectangle aRect( maDropPos, aSize ); |
1044 | 0 | rtl::Reference<SdrOle2Obj> pObj = new SdrOle2Obj( |
1045 | 0 | getSdrModelFromSdrView(), |
1046 | 0 | aObjRef, |
1047 | 0 | aName, |
1048 | 0 | aRect); |
1049 | 0 | SdrPageView* pPV = GetSdrPageView(); |
1050 | 0 | SdrInsertFlags nOptions = SdrInsertFlags::SETDEFLAYER; |
1051 | |
|
1052 | 0 | if (mpViewSh!=nullptr) |
1053 | 0 | { |
1054 | 0 | OSL_ASSERT (mpViewSh->GetViewShell()!=nullptr); |
1055 | 0 | SfxInPlaceClient* pIpClient |
1056 | 0 | = mpViewSh->GetViewShell()->GetIPClient(); |
1057 | 0 | if (pIpClient!=nullptr && pIpClient->IsObjectInPlaceActive()) |
1058 | 0 | nOptions |= SdrInsertFlags::DONTMARK; |
1059 | 0 | } |
1060 | | |
1061 | | // bInserted of false means that pObj has been deleted |
1062 | 0 | bool bInserted = InsertObjectAtView( pObj.get(), *pPV, nOptions ); |
1063 | |
|
1064 | 0 | if (bInserted && pImageMap) |
1065 | 0 | pObj->AppendUserData( std::unique_ptr<SdrObjUserData>(new SvxIMapInfo( *pImageMap )) ); |
1066 | |
|
1067 | 0 | if (bInserted && pObj->IsChart()) |
1068 | 0 | { |
1069 | 0 | bool bDisableDataTableDialog = false; |
1070 | 0 | svt::EmbeddedObjectRef::TryRunningState( xObj ); |
1071 | 0 | uno::Reference< beans::XPropertySet > xProps( xObj->getComponent(), uno::UNO_QUERY ); |
1072 | 0 | if ( xProps.is() && |
1073 | 0 | ( xProps->getPropertyValue( u"DisableDataTableDialog"_ustr ) >>= bDisableDataTableDialog ) && |
1074 | 0 | bDisableDataTableDialog ) |
1075 | 0 | { |
1076 | 0 | xProps->setPropertyValue( u"DisableDataTableDialog"_ustr , uno::Any( false ) ); |
1077 | 0 | xProps->setPropertyValue( u"DisableComplexChartTypes"_ustr , uno::Any( false ) ); |
1078 | 0 | uno::Reference< util::XModifiable > xModifiable( xProps, uno::UNO_QUERY ); |
1079 | 0 | if ( xModifiable.is() ) |
1080 | 0 | { |
1081 | 0 | xModifiable->setModified( true ); |
1082 | 0 | } |
1083 | 0 | } |
1084 | 0 | } |
1085 | |
|
1086 | 0 | return true; |
1087 | 0 | } |
1088 | 0 | } |
1089 | 0 | } |
1090 | 0 | } |
1091 | | |
1092 | 0 | if (!bLink && |
1093 | 0 | (ShouldTry(SotClipboardFormatId::EMBEDDED_OBJ_OLE) || ShouldTry(SotClipboardFormatId::EMBED_SOURCE_OLE)) && |
1094 | 0 | rDataHelper.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR_OLE)) |
1095 | 0 | { |
1096 | | // online insert ole if format is forced or no gdi metafile is available |
1097 | 0 | if( (nFormat != SotClipboardFormatId::NONE) || !rDataHelper.HasFormat( SotClipboardFormatId::GDIMETAFILE ) ) |
1098 | 0 | { |
1099 | 0 | uno::Reference < io::XInputStream > xStm; |
1100 | 0 | TransferableObjectDescriptor aObjDesc; |
1101 | |
|
1102 | 0 | if ( rDataHelper.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR_OLE, aObjDesc ) ) |
1103 | 0 | { |
1104 | 0 | uno::Reference < embed::XEmbeddedObject > xObj; |
1105 | 0 | OUString aName; |
1106 | |
|
1107 | 0 | xStm = rDataHelper.GetInputStream(nFormat != SotClipboardFormatId::NONE ? nFormat : SotClipboardFormatId::EMBED_SOURCE_OLE, OUString()); |
1108 | 0 | if (!xStm.is()) |
1109 | 0 | xStm = rDataHelper.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ_OLE, OUString()); |
1110 | |
|
1111 | 0 | if (xStm.is()) |
1112 | 0 | { |
1113 | 0 | xObj = mpDocSh->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName ); |
1114 | 0 | } |
1115 | 0 | else |
1116 | 0 | { |
1117 | 0 | try |
1118 | 0 | { |
1119 | 0 | uno::Reference< embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage(); |
1120 | 0 | uno::Reference < embed::XEmbedObjectClipboardCreator > xClipboardCreator = |
1121 | 0 | embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() ); |
1122 | |
|
1123 | 0 | embed::InsertedObjectInfo aInfo = xClipboardCreator->createInstanceInitFromClipboard( |
1124 | 0 | xTmpStor, |
1125 | 0 | u"DummyName"_ustr , |
1126 | 0 | uno::Sequence< beans::PropertyValue >() ); |
1127 | | |
1128 | | // TODO/LATER: in future InsertedObjectInfo will be used to get container related information |
1129 | | // for example whether the object should be an iconified one |
1130 | 0 | xObj = aInfo.Object; |
1131 | 0 | if ( xObj.is() ) |
1132 | 0 | mpDocSh->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj, aName ); |
1133 | 0 | } |
1134 | 0 | catch( uno::Exception& ) |
1135 | 0 | {} |
1136 | 0 | } |
1137 | |
|
1138 | 0 | if ( xObj.is() ) |
1139 | 0 | { |
1140 | 0 | svt::EmbeddedObjectRef aObjRef( xObj, aObjDesc.mnViewAspect ); |
1141 | | |
1142 | | // try to get the replacement image from the clipboard |
1143 | 0 | Graphic aGraphic; |
1144 | 0 | SotClipboardFormatId nGrFormat = SotClipboardFormatId::NONE; |
1145 | | |
1146 | | // (for Selection Manager in Trusted Solaris) |
1147 | 0 | #ifndef __sun |
1148 | 0 | if (rDataHelper.GetGraphic(SotClipboardFormatId::SVXB, aGraphic)) |
1149 | 0 | nGrFormat = SotClipboardFormatId::SVXB; |
1150 | 0 | else if (rDataHelper.GetGraphic(SotClipboardFormatId::GDIMETAFILE, aGraphic)) |
1151 | 0 | nGrFormat = SotClipboardFormatId::GDIMETAFILE; |
1152 | 0 | else if (rDataHelper.GetGraphic(SotClipboardFormatId::BITMAP, aGraphic)) |
1153 | 0 | nGrFormat = SotClipboardFormatId::BITMAP; |
1154 | 0 | #endif |
1155 | | |
1156 | | // insert replacement image ( if there is one ) into the object helper |
1157 | 0 | if ( nGrFormat != SotClipboardFormatId::NONE ) |
1158 | 0 | { |
1159 | 0 | datatransfer::DataFlavor aDataFlavor; |
1160 | 0 | SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor ); |
1161 | 0 | aObjRef.SetGraphic( aGraphic, aDataFlavor.MimeType ); |
1162 | 0 | } |
1163 | |
|
1164 | 0 | Size aSize; |
1165 | 0 | if ( aObjDesc.mnViewAspect == embed::Aspects::MSOLE_ICON ) |
1166 | 0 | { |
1167 | 0 | if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() ) |
1168 | 0 | aSize = aObjDesc.maSize; |
1169 | 0 | else |
1170 | 0 | { |
1171 | 0 | MapMode aMapMode( MapUnit::Map100thMM ); |
1172 | 0 | aSize = aObjRef.GetSize( &aMapMode ); |
1173 | 0 | } |
1174 | 0 | } |
1175 | 0 | else |
1176 | 0 | { |
1177 | 0 | MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( aObjDesc.mnViewAspect ) ); |
1178 | |
|
1179 | 0 | awt::Size aSz; |
1180 | 0 | try{ |
1181 | 0 | aSz = xObj->getVisualAreaSize( aObjDesc.mnViewAspect ); |
1182 | 0 | } |
1183 | 0 | catch( embed::NoVisualAreaSizeException& ) |
1184 | 0 | { |
1185 | | // the default size will be set later |
1186 | 0 | } |
1187 | |
|
1188 | 0 | if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() ) |
1189 | 0 | { |
1190 | 0 | Size aTmp(OutputDevice::LogicToLogic(aObjDesc.maSize, MapMode(MapUnit::Map100thMM), MapMode(aMapUnit))); |
1191 | 0 | if ( aSz.Width != aTmp.Width() || aSz.Height != aTmp.Height() ) |
1192 | 0 | { |
1193 | 0 | aSz.Width = aTmp.Width(); |
1194 | 0 | aSz.Height = aTmp.Height(); |
1195 | 0 | xObj->setVisualAreaSize( aObjDesc.mnViewAspect, aSz ); |
1196 | 0 | } |
1197 | 0 | } |
1198 | |
|
1199 | 0 | aSize = Size( aSz.Width, aSz.Height ); |
1200 | |
|
1201 | 0 | if( !aSize.Width() || !aSize.Height() ) |
1202 | 0 | { |
1203 | 0 | aSize = OutputDevice::LogicToLogic(Size(14100, 10000), MapMode(MapUnit::Map100thMM), MapMode(aMapUnit)); |
1204 | 0 | aSz.Width = aSize.Width(); |
1205 | 0 | aSz.Height = aSize.Height(); |
1206 | 0 | xObj->setVisualAreaSize( aObjDesc.mnViewAspect, aSz ); |
1207 | 0 | } |
1208 | |
|
1209 | 0 | aSize = OutputDevice::LogicToLogic(aSize, MapMode(aMapUnit), MapMode(MapUnit::Map100thMM)); |
1210 | 0 | } |
1211 | |
|
1212 | 0 | Size aMaxSize( mrDoc.GetMaxObjSize() ); |
1213 | |
|
1214 | 0 | maDropPos.AdjustX( -(std::min( aSize.Width(), aMaxSize.Width() ) >> 1) ); |
1215 | 0 | maDropPos.AdjustY( -(std::min( aSize.Height(), aMaxSize.Height() ) >> 1) ); |
1216 | |
|
1217 | 0 | ::tools::Rectangle aRect( maDropPos, aSize ); |
1218 | 0 | rtl::Reference<SdrOle2Obj> pObj = new SdrOle2Obj( |
1219 | 0 | getSdrModelFromSdrView(), |
1220 | 0 | aObjRef, |
1221 | 0 | aName, |
1222 | 0 | aRect); |
1223 | 0 | SdrPageView* pPV = GetSdrPageView(); |
1224 | 0 | SdrInsertFlags nOptions = SdrInsertFlags::SETDEFLAYER; |
1225 | |
|
1226 | 0 | if (mpViewSh!=nullptr) |
1227 | 0 | { |
1228 | 0 | OSL_ASSERT (mpViewSh->GetViewShell()!=nullptr); |
1229 | 0 | SfxInPlaceClient* pIpClient |
1230 | 0 | = mpViewSh->GetViewShell()->GetIPClient(); |
1231 | 0 | if (pIpClient!=nullptr && pIpClient->IsObjectInPlaceActive()) |
1232 | 0 | nOptions |= SdrInsertFlags::DONTMARK; |
1233 | 0 | } |
1234 | |
|
1235 | 0 | if (InsertObjectAtView(pObj.get(), *pPV, nOptions)) |
1236 | 0 | { |
1237 | 0 | if( pImageMap ) |
1238 | 0 | pObj->AppendUserData( std::unique_ptr<SdrObjUserData>(new SvxIMapInfo( *pImageMap )) ); |
1239 | | |
1240 | | // let the object stay in loaded state after insertion |
1241 | 0 | pObj->Unload(); |
1242 | 0 | return true; |
1243 | 0 | } |
1244 | 0 | } |
1245 | 0 | } |
1246 | 0 | } |
1247 | | |
1248 | 0 | if (rDataHelper.HasFormat(SotClipboardFormatId::GDIMETAFILE)) |
1249 | 0 | { |
1250 | | // if no object was inserted, insert a picture |
1251 | 0 | InsertMetaFile(rDataHelper, rPos, pImageMap.get(), true); |
1252 | 0 | return true; |
1253 | 0 | } |
1254 | 0 | } |
1255 | | |
1256 | 0 | if ((!bLink || pPickObj) && ShouldTry(SotClipboardFormatId::SVXB)) |
1257 | 0 | { |
1258 | 0 | if (std::unique_ptr<SvStream> xStm = rDataHelper.GetSotStorageStream( SotClipboardFormatId::SVXB )) |
1259 | 0 | { |
1260 | 0 | Point aInsertPos( rPos ); |
1261 | 0 | Graphic aGraphic; |
1262 | |
|
1263 | 0 | TypeSerializer aSerializer(*xStm); |
1264 | 0 | aSerializer.readGraphic(aGraphic); |
1265 | |
|
1266 | 0 | if( pOwnData && pOwnData->GetWorkDocument() ) |
1267 | 0 | { |
1268 | 0 | const SdDrawDocument* pWorkModel = pOwnData->GetWorkDocument(); |
1269 | 0 | SdrPage* pWorkPage = const_cast<SdrPage*>( ( pWorkModel->GetPageCount() > 1 ) ? |
1270 | 0 | pWorkModel->GetSdPage( 0, PageKind::Standard ) : |
1271 | 0 | pWorkModel->GetPage( 0 ) ); |
1272 | |
|
1273 | 0 | pWorkPage->SetSdrObjListRectsDirty(); |
1274 | | |
1275 | | // tdf#118171 - snap rectangles of objects without line width |
1276 | 0 | const Size aSize(pWorkPage->GetAllObjSnapRect().GetSize()); |
1277 | |
|
1278 | 0 | aInsertPos.setX( pOwnData->GetBoundStartPos().X() + ( aSize.Width() >> 1 ) ); |
1279 | 0 | aInsertPos.setY( pOwnData->GetBoundStartPos().Y() + ( aSize.Height() >> 1 ) ); |
1280 | 0 | } |
1281 | | |
1282 | | // restrict movement to WorkArea |
1283 | 0 | Size aImageMapSize = OutputDevice::LogicToLogic(aGraphic.GetPrefSize(), |
1284 | 0 | aGraphic.GetPrefMapMode(), MapMode(MapUnit::Map100thMM)); |
1285 | |
|
1286 | 0 | ImpCheckInsertPos(aInsertPos, aImageMapSize, GetWorkArea()); |
1287 | |
|
1288 | 0 | InsertGraphic( aGraphic, mnAction, aInsertPos, nullptr, pImageMap.get() ); |
1289 | 0 | return true; |
1290 | 0 | } |
1291 | 0 | } |
1292 | | |
1293 | 0 | if ((!bLink || pPickObj) && ShouldTry(SotClipboardFormatId::GDIMETAFILE)) |
1294 | 0 | { |
1295 | 0 | Point aInsertPos( rPos ); |
1296 | |
|
1297 | 0 | if( pOwnData && pOwnData->GetWorkDocument() ) |
1298 | | |
1299 | 0 | { |
1300 | 0 | const SdDrawDocument* pWorkModel = pOwnData->GetWorkDocument(); |
1301 | 0 | SdrPage* pWorkPage = const_cast<SdrPage*>( ( pWorkModel->GetPageCount() > 1 ) ? |
1302 | 0 | pWorkModel->GetSdPage( 0, PageKind::Standard ) : |
1303 | 0 | pWorkModel->GetPage( 0 ) ); |
1304 | |
|
1305 | 0 | pWorkPage->SetSdrObjListRectsDirty(); |
1306 | | |
1307 | | // tdf#118171 - snap rectangles of objects without line width |
1308 | 0 | const Size aSize(pWorkPage->GetAllObjSnapRect().GetSize()); |
1309 | |
|
1310 | 0 | aInsertPos.setX( pOwnData->GetBoundStartPos().X() + ( aSize.Width() >> 1 ) ); |
1311 | 0 | aInsertPos.setY( pOwnData->GetBoundStartPos().Y() + ( aSize.Height() >> 1 ) ); |
1312 | 0 | } |
1313 | |
|
1314 | 0 | if (InsertMetaFile( rDataHelper, aInsertPos, pImageMap.get(), nFormat == SotClipboardFormatId::NONE )) |
1315 | 0 | return true; |
1316 | 0 | } |
1317 | | |
1318 | 0 | if ((!bLink || pPickObj) && ShouldTry(SotClipboardFormatId::BITMAP)) |
1319 | 0 | { |
1320 | 0 | Bitmap aBmp; |
1321 | | |
1322 | | // get basic Bitmap data |
1323 | 0 | rDataHelper.GetBitmap(SotClipboardFormatId::BITMAP, aBmp); |
1324 | |
|
1325 | 0 | if(aBmp.IsEmpty()) |
1326 | 0 | { |
1327 | | // if this did not work, try to get graphic formats and convert these to bitmap |
1328 | 0 | Graphic aGraphic; |
1329 | |
|
1330 | 0 | if (rDataHelper.GetGraphic(SotClipboardFormatId::GDIMETAFILE, aGraphic)) |
1331 | 0 | { |
1332 | 0 | aBmp = aGraphic.GetBitmap(); |
1333 | 0 | } |
1334 | 0 | else if (rDataHelper.GetGraphic(SotClipboardFormatId::SVXB, aGraphic)) |
1335 | 0 | { |
1336 | 0 | aBmp = aGraphic.GetBitmap(); |
1337 | 0 | } |
1338 | 0 | else if (rDataHelper.GetGraphic(SotClipboardFormatId::BITMAP, aGraphic)) |
1339 | 0 | { |
1340 | 0 | aBmp = aGraphic.GetBitmap(); |
1341 | 0 | } |
1342 | 0 | } |
1343 | |
|
1344 | 0 | if(!aBmp.IsEmpty()) |
1345 | 0 | { |
1346 | 0 | Point aInsertPos( rPos ); |
1347 | |
|
1348 | 0 | if( pOwnData && pOwnData->GetWorkDocument() ) |
1349 | 0 | { |
1350 | 0 | const SdDrawDocument* pWorkModel = pOwnData->GetWorkDocument(); |
1351 | 0 | SdrPage* pWorkPage = const_cast<SdrPage*>( ( pWorkModel->GetPageCount() > 1 ) ? |
1352 | 0 | pWorkModel->GetSdPage( 0, PageKind::Standard ) : |
1353 | 0 | pWorkModel->GetPage( 0 ) ); |
1354 | |
|
1355 | 0 | pWorkPage->SetSdrObjListRectsDirty(); |
1356 | | |
1357 | | // tdf#118171 - snap rectangles of objects without line width |
1358 | 0 | const Size aSize(pWorkPage->GetAllObjSnapRect().GetSize()); |
1359 | |
|
1360 | 0 | aInsertPos.setX( pOwnData->GetBoundStartPos().X() + ( aSize.Width() >> 1 ) ); |
1361 | 0 | aInsertPos.setY( pOwnData->GetBoundStartPos().Y() + ( aSize.Height() >> 1 ) ); |
1362 | 0 | } |
1363 | | |
1364 | | // restrict movement to WorkArea |
1365 | 0 | Size aImageMapSize(aBmp.GetPrefSize()); |
1366 | 0 | ImpCheckInsertPos(aInsertPos, aImageMapSize, GetWorkArea()); |
1367 | |
|
1368 | 0 | InsertGraphic( aBmp, mnAction, aInsertPos, nullptr, pImageMap.get() ); |
1369 | 0 | return true; |
1370 | 0 | } |
1371 | 0 | } |
1372 | | |
1373 | 0 | if (pPickObj && ShouldTry(SotClipboardFormatId::XFA)) |
1374 | 0 | { |
1375 | 0 | uno::Any const data(rDataHelper.GetAny(SotClipboardFormatId::XFA, u""_ustr)); |
1376 | 0 | uno::Sequence<beans::NamedValue> props; |
1377 | 0 | if (data >>= props) |
1378 | 0 | { |
1379 | 0 | if( IsUndoEnabled() ) |
1380 | 0 | { |
1381 | 0 | BegUndo( SdResId(STR_UNDO_DRAGDROP) ); |
1382 | 0 | AddUndo(GetModel().GetSdrUndoFactory().CreateUndoAttrObject(*pPickObj)); |
1383 | 0 | EndUndo(); |
1384 | 0 | } |
1385 | |
|
1386 | 0 | ::comphelper::SequenceAsHashMap const map(props); |
1387 | 0 | drawing::FillStyle eFill(drawing::FillStyle_BITMAP); // default to something that's ignored |
1388 | 0 | Color aColor(COL_BLACK); |
1389 | 0 | auto it = map.find(u"FillStyle"_ustr); |
1390 | 0 | if (it != map.end()) |
1391 | 0 | { |
1392 | 0 | XFillStyleItem style; |
1393 | 0 | style.PutValue(it->second, 0); |
1394 | 0 | eFill = style.GetValue(); |
1395 | 0 | } |
1396 | 0 | it = map.find(u"FillColor"_ustr); |
1397 | 0 | if (it != map.end()) |
1398 | 0 | { |
1399 | 0 | XFillColorItem color; |
1400 | 0 | color.PutValue(it->second, 0); |
1401 | 0 | aColor = color.GetColorValue(); |
1402 | 0 | } |
1403 | |
|
1404 | 0 | if( eFill == drawing::FillStyle_SOLID || eFill == drawing::FillStyle_NONE ) |
1405 | 0 | { |
1406 | 0 | SfxItemSet aSet( mrDoc.GetPool() ); |
1407 | 0 | bool bClosed = pPickObj->IsClosedObj(); |
1408 | 0 | ::sd::Window* pWin = mpViewSh->GetActiveWindow(); |
1409 | 0 | double fHitLog = pWin->PixelToLogic(Size(FuPoor::HITPIX, 0 ) ).Width(); |
1410 | 0 | const ::tools::Long n2HitLog = fHitLog * 2; |
1411 | 0 | Point aHitPosR( rPos ); |
1412 | 0 | Point aHitPosL( rPos ); |
1413 | 0 | Point aHitPosT( rPos ); |
1414 | 0 | Point aHitPosB( rPos ); |
1415 | 0 | const SdrLayerIDSet* pVisiLayer = &GetSdrPageView()->GetVisibleLayers(); |
1416 | |
|
1417 | 0 | aHitPosR.AdjustX(n2HitLog ); |
1418 | 0 | aHitPosL.AdjustX( -n2HitLog ); |
1419 | 0 | aHitPosT.AdjustY(n2HitLog ); |
1420 | 0 | aHitPosB.AdjustY( -n2HitLog ); |
1421 | |
|
1422 | 0 | if( bClosed && |
1423 | 0 | SdrObjectPrimitiveHit(*pPickObj, aHitPosR, {fHitLog, fHitLog}, *GetSdrPageView(), pVisiLayer, false) && |
1424 | 0 | SdrObjectPrimitiveHit(*pPickObj, aHitPosL, {fHitLog, fHitLog}, *GetSdrPageView(), pVisiLayer, false) && |
1425 | 0 | SdrObjectPrimitiveHit(*pPickObj, aHitPosT, {fHitLog, fHitLog}, *GetSdrPageView(), pVisiLayer, false) && |
1426 | 0 | SdrObjectPrimitiveHit(*pPickObj, aHitPosB, {fHitLog, fHitLog}, *GetSdrPageView(), pVisiLayer, false) ) |
1427 | 0 | { |
1428 | | // area fill |
1429 | 0 | if(eFill == drawing::FillStyle_SOLID ) |
1430 | 0 | aSet.Put(XFillColorItem(u""_ustr, aColor)); |
1431 | |
|
1432 | 0 | aSet.Put( XFillStyleItem( eFill ) ); |
1433 | 0 | } |
1434 | 0 | else |
1435 | 0 | aSet.Put( XLineColorItem( u""_ustr, aColor ) ); |
1436 | | |
1437 | | // add text color |
1438 | 0 | pPickObj->SetMergedItemSetAndBroadcast( aSet ); |
1439 | 0 | } |
1440 | 0 | return true; |
1441 | 0 | } |
1442 | 0 | } |
1443 | | |
1444 | 0 | if (!bLink && ShouldTry(SotClipboardFormatId::HTML)) |
1445 | 0 | { |
1446 | 0 | if (std::unique_ptr<SvStream> xStm = rDataHelper.GetSotStorageStream( SotClipboardFormatId::HTML )) |
1447 | 0 | { |
1448 | 0 | xStm->Seek( 0 ); |
1449 | |
|
1450 | 0 | OStringBuffer aLine; |
1451 | 0 | while (xStm->ReadLine(aLine)) |
1452 | 0 | { |
1453 | 0 | if (std::string_view(aLine).find( "<table>" ) != std::string_view::npos || |
1454 | 0 | std::string_view(aLine).find( "<table " ) != std::string_view::npos) |
1455 | 0 | { |
1456 | 0 | bTable = true; |
1457 | 0 | break; |
1458 | 0 | } |
1459 | 0 | } |
1460 | |
|
1461 | 0 | xStm->Seek( 0 ); |
1462 | 0 | if (bTable) |
1463 | 0 | { |
1464 | 0 | if (PasteHTMLTable(*xStm, pPage, nPasteOptions)) |
1465 | 0 | return true; |
1466 | 0 | } |
1467 | 0 | else |
1468 | 0 | { |
1469 | 0 | OutlinerView* pOLV = GetTextEditOutlinerView(); |
1470 | |
|
1471 | 0 | if (pOLV) |
1472 | 0 | { |
1473 | 0 | ::tools::Rectangle aRect(pOLV->GetOutputArea()); |
1474 | 0 | Point aPos(pOLV->GetWindow()->PixelToLogic(maDropPos)); |
1475 | |
|
1476 | 0 | if (aRect.Contains(aPos) || (!bDrag && IsTextEdit()) |
1477 | 0 | || dynamic_cast<sd::NotesPanelViewShell*>(mpViewSh)) |
1478 | 0 | { |
1479 | 0 | pOLV->Read(*xStm, EETextFormat::Html, mpDocSh->GetHeaderAttributes()); |
1480 | 0 | return true; |
1481 | 0 | } |
1482 | 0 | } |
1483 | | |
1484 | | // mba: clipboard always must contain absolute URLs (could be from alien source) |
1485 | 0 | if (SdrView::Paste(*xStm, EETextFormat::Html, maDropPos, pPage, nPasteOptions)) |
1486 | 0 | return true; |
1487 | 0 | } |
1488 | 0 | } |
1489 | 0 | } |
1490 | | |
1491 | 0 | if (!bLink && ShouldTry(SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT)) |
1492 | 0 | { |
1493 | 0 | if (std::unique_ptr<SvStream> xStm = rDataHelper.GetSotStorageStream( SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT )) |
1494 | 0 | { |
1495 | 0 | OutlinerView* pOLV = GetTextEditOutlinerView(); |
1496 | |
|
1497 | 0 | xStm->Seek( 0 ); |
1498 | |
|
1499 | 0 | if( pOLV ) |
1500 | 0 | { |
1501 | 0 | ::tools::Rectangle aRect( pOLV->GetOutputArea() ); |
1502 | 0 | Point aPos( pOLV->GetWindow()->PixelToLogic( maDropPos ) ); |
1503 | |
|
1504 | 0 | if (aRect.Contains(aPos) || (!bDrag && IsTextEdit()) |
1505 | 0 | || dynamic_cast<sd::NotesPanelViewShell*>(mpViewSh)) |
1506 | 0 | { |
1507 | | // mba: clipboard always must contain absolute URLs (could be from alien source) |
1508 | 0 | pOLV->Read( *xStm, EETextFormat::Xml, mpDocSh->GetHeaderAttributes() ); |
1509 | 0 | return true; |
1510 | 0 | } |
1511 | 0 | } |
1512 | | |
1513 | | // mba: clipboard always must contain absolute URLs (could be from alien source) |
1514 | 0 | if (SdrView::Paste(*xStm, EETextFormat::Xml, maDropPos, pPage, nPasteOptions)) |
1515 | 0 | return true; |
1516 | 0 | } |
1517 | 0 | } |
1518 | | |
1519 | 0 | if (!bLink) |
1520 | 0 | { |
1521 | 0 | if (ShouldTry(SotClipboardFormatId::HTML_SIMPLE)) |
1522 | 0 | { |
1523 | 0 | if (std::unique_ptr<SvStream> xStm = rDataHelper.GetSotStorageStream(SotClipboardFormatId::HTML_SIMPLE)) |
1524 | 0 | { |
1525 | 0 | xStm->Seek(0); |
1526 | |
|
1527 | 0 | OutlinerView* pOLV = GetTextEditOutlinerView(); |
1528 | 0 | MSE40HTMLClipFormatObj aMSE40HTMLClipFormatObj; |
1529 | 0 | SvStream* pHtmlStream = aMSE40HTMLClipFormatObj.IsValid(*xStm); |
1530 | |
|
1531 | 0 | if (pOLV) |
1532 | 0 | { |
1533 | 0 | ::tools::Rectangle aRect(pOLV->GetOutputArea()); |
1534 | 0 | Point aPos(pOLV->GetWindow()->PixelToLogic(maDropPos)); |
1535 | |
|
1536 | 0 | if (aRect.Contains(aPos) || (!bDrag && IsTextEdit()) |
1537 | 0 | || dynamic_cast<sd::NotesPanelViewShell*>(mpViewSh)) |
1538 | 0 | { |
1539 | | // mba: clipboard always must contain absolute URLs (could be from alien source) |
1540 | 0 | pOLV->Read(*pHtmlStream, EETextFormat::Html, mpDocSh->GetHeaderAttributes()); |
1541 | 0 | return true; |
1542 | 0 | } |
1543 | 0 | } |
1544 | | |
1545 | | // mba: clipboard always must contain absolute URLs (could be from alien source) |
1546 | 0 | if (SdrView::Paste(*pHtmlStream, EETextFormat::Html, maDropPos, pPage, nPasteOptions)) |
1547 | 0 | return true; |
1548 | 0 | } |
1549 | 0 | } |
1550 | | |
1551 | 0 | bool bIsRTF = ShouldTry(SotClipboardFormatId::RTF); |
1552 | 0 | if (bIsRTF || ShouldTry(SotClipboardFormatId::RICHTEXT)) |
1553 | 0 | { |
1554 | 0 | auto nFormatId = bIsRTF ? SotClipboardFormatId::RTF : SotClipboardFormatId::RICHTEXT; |
1555 | 0 | if (std::unique_ptr<SvStream> xStm = rDataHelper.GetSotStorageStream(nFormatId)) |
1556 | 0 | { |
1557 | 0 | xStm->Seek( 0 ); |
1558 | |
|
1559 | 0 | if( bTable ) |
1560 | 0 | { |
1561 | 0 | if (PasteRTFTable(*xStm, pPage, nPasteOptions)) |
1562 | 0 | return true; |
1563 | 0 | } |
1564 | 0 | else |
1565 | 0 | { |
1566 | 0 | OutlinerView* pOLV = GetTextEditOutlinerView(); |
1567 | |
|
1568 | 0 | if( pOLV ) |
1569 | 0 | { |
1570 | 0 | ::tools::Rectangle aRect( pOLV->GetOutputArea() ); |
1571 | 0 | Point aPos( pOLV->GetWindow()->PixelToLogic( maDropPos ) ); |
1572 | |
|
1573 | 0 | if (aRect.Contains(aPos) || (!bDrag && IsTextEdit()) |
1574 | 0 | || dynamic_cast<sd::NotesPanelViewShell*>(mpViewSh)) |
1575 | 0 | { |
1576 | | // mba: clipboard always must contain absolute URLs (could be from alien source) |
1577 | 0 | pOLV->Read( *xStm, EETextFormat::Rtf, mpDocSh->GetHeaderAttributes() ); |
1578 | 0 | return true; |
1579 | 0 | } |
1580 | 0 | } |
1581 | | |
1582 | | // mba: clipboard always must contain absolute URLs (could be from alien source) |
1583 | 0 | if (SdrView::Paste(*xStm, EETextFormat::Rtf, maDropPos, pPage, nPasteOptions)) |
1584 | 0 | return true; |
1585 | 0 | } |
1586 | 0 | } |
1587 | 0 | } |
1588 | |
|
1589 | 0 | } |
1590 | | |
1591 | 0 | if (ShouldTry(SotClipboardFormatId::FILE_LIST)) |
1592 | 0 | { |
1593 | 0 | FileList aDropFileList; |
1594 | |
|
1595 | 0 | if (rDataHelper.GetFileList(SotClipboardFormatId::FILE_LIST, aDropFileList)) |
1596 | 0 | { |
1597 | 0 | maDropFileVector.clear(); |
1598 | |
|
1599 | 0 | for( size_t i = 0, nCount = aDropFileList.Count(); i < nCount; i++ ) |
1600 | 0 | maDropFileVector.push_back( aDropFileList.GetFile( i ) ); |
1601 | |
|
1602 | 0 | maDropInsertFileIdle.Start(); |
1603 | 0 | } |
1604 | |
|
1605 | 0 | return true; |
1606 | 0 | } |
1607 | | |
1608 | 0 | if (ShouldTry(SotClipboardFormatId::SIMPLE_FILE)) |
1609 | 0 | { |
1610 | 0 | OUString aDropFile; |
1611 | |
|
1612 | 0 | if (rDataHelper.GetString(SotClipboardFormatId::SIMPLE_FILE, aDropFile)) |
1613 | 0 | { |
1614 | 0 | maDropFileVector.clear(); |
1615 | 0 | maDropFileVector.push_back( aDropFile ); |
1616 | 0 | maDropInsertFileIdle.Start(); |
1617 | 0 | } |
1618 | |
|
1619 | 0 | return true; |
1620 | 0 | } |
1621 | | |
1622 | 0 | if (!bLink && ShouldTry(SotClipboardFormatId::STRING)) |
1623 | 0 | { |
1624 | 0 | if( ( SotClipboardFormatId::STRING == nFormat ) || |
1625 | 0 | ( !rDataHelper.HasFormat( SotClipboardFormatId::SOLK ) && |
1626 | 0 | !rDataHelper.HasFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK ) && |
1627 | 0 | !rDataHelper.HasFormat( SotClipboardFormatId::FILENAME ) ) ) |
1628 | 0 | { |
1629 | 0 | OUString aOUString; |
1630 | |
|
1631 | 0 | if (rDataHelper.GetString(SotClipboardFormatId::STRING, aOUString)) |
1632 | 0 | { |
1633 | 0 | OutlinerView* pOLV = GetTextEditOutlinerView(); |
1634 | |
|
1635 | 0 | if( pOLV ) |
1636 | 0 | { |
1637 | | // tdf#139269 - prevent text pasting into readonly areas of master views |
1638 | 0 | if (!pPage) |
1639 | 0 | pPage = static_cast<SdPage*>(GetSdrPageView()->GetPage()); |
1640 | |
|
1641 | 0 | if (pPage && pPage->IsMasterPage() && pOLV->IsReadOnly()) |
1642 | 0 | return false; |
1643 | | |
1644 | 0 | pOLV->InsertText( aOUString ); |
1645 | 0 | return true; |
1646 | 0 | } |
1647 | | |
1648 | 0 | if (SdrView::Paste(aOUString, maDropPos, pPage, nPasteOptions)) |
1649 | 0 | return true; |
1650 | 0 | } |
1651 | 0 | } |
1652 | 0 | } |
1653 | | |
1654 | 0 | return false; |
1655 | 0 | } |
1656 | | |
1657 | | bool View::PasteRTFTable( SvStream& rStm, SdrPage* pPage, SdrInsertFlags nPasteOptions ) |
1658 | 0 | { |
1659 | 0 | DrawDocShellRef xShell = new DrawDocShell(SfxObjectCreateMode::INTERNAL, false, DocumentType::Impress); |
1660 | 0 | xShell->DoInitNew(); |
1661 | |
|
1662 | 0 | SdDrawDocument* pModel = xShell->GetDoc(); |
1663 | 0 | pModel->GetItemPool().SetDefaultMetric(MapUnit::Map100thMM); |
1664 | 0 | pModel->InsertPage(pModel->AllocPage(false).get()); |
1665 | |
|
1666 | 0 | CreateTableFromRTF(rStm, pModel); |
1667 | 0 | bool bRet = Paste(*pModel, maDropPos, pPage, nPasteOptions); |
1668 | |
|
1669 | 0 | xShell->DoClose(); |
1670 | |
|
1671 | 0 | return bRet; |
1672 | 0 | } |
1673 | | |
1674 | | bool View::PasteHTMLTable( SvStream& rStm, SdrPage* pPage, SdrInsertFlags nPasteOptions ) |
1675 | 0 | { |
1676 | 0 | DrawDocShellRef xShell = new DrawDocShell(SfxObjectCreateMode::INTERNAL, false, DocumentType::Impress); |
1677 | 0 | xShell->DoInitNew(); |
1678 | |
|
1679 | 0 | SdDrawDocument* pModel = xShell->GetDoc(); |
1680 | 0 | pModel->GetItemPool().SetDefaultMetric(MapUnit::Map100thMM); |
1681 | 0 | pModel->InsertPage(pModel->AllocPage(false).get()); |
1682 | |
|
1683 | 0 | CreateTableFromHTML(rStm, pModel); |
1684 | 0 | bool bRet = Paste(*pModel, maDropPos, pPage, nPasteOptions); |
1685 | |
|
1686 | 0 | xShell->DoClose(); |
1687 | |
|
1688 | 0 | return bRet; |
1689 | 0 | } |
1690 | | } // end of namespace sd |
1691 | | |
1692 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |