File: | home/maarten/src/libreoffice/core/include/tools/ref.hxx |
Warning: | line 71, column 13 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 <sal/config.h> | |||
21 | ||||
22 | #include <com/sun/star/embed/XEmbeddedObject.hpp> | |||
23 | #include <com/sun/star/embed/XTransactedObject.hpp> | |||
24 | #include <com/sun/star/embed/XEmbedPersist.hpp> | |||
25 | #include <com/sun/star/embed/ElementModes.hpp> | |||
26 | #include <com/sun/star/lang/XComponent.hpp> | |||
27 | #include <comphelper/fileformat.h> | |||
28 | #include <unotools/ucbstreamhelper.hxx> | |||
29 | #include <unotools/tempfile.hxx> | |||
30 | #include <editeng/flditem.hxx> | |||
31 | #include <svx/svdpagv.hxx> | |||
32 | #include <svx/svdoole2.hxx> | |||
33 | #include <svx/svdograf.hxx> | |||
34 | #include <svx/svdotext.hxx> | |||
35 | #include <editeng/outlobj.hxx> | |||
36 | #include <sot/storage.hxx> | |||
37 | #include <editeng/editobj.hxx> | |||
38 | #include <svx/fmglob.hxx> | |||
39 | #include <svx/svdouno.hxx> | |||
40 | #include <svx/ImageMapInfo.hxx> | |||
41 | #include <sot/formats.hxx> | |||
42 | #include <svl/urlbmk.hxx> | |||
43 | ||||
44 | #include <com/sun/star/form/FormButtonType.hpp> | |||
45 | #include <com/sun/star/beans/XPropertySet.hpp> | |||
46 | #include <unotools/streamwrap.hxx> | |||
47 | ||||
48 | #include <svx/svdotable.hxx> | |||
49 | #include <svx/unomodel.hxx> | |||
50 | #include <svx/svditer.hxx> | |||
51 | #include <sfx2/docfile.hxx> | |||
52 | #include <comphelper/storagehelper.hxx> | |||
53 | #include <comphelper/servicehelper.hxx> | |||
54 | #include <svtools/embedtransfer.hxx> | |||
55 | #include <DrawDocShell.hxx> | |||
56 | #include <View.hxx> | |||
57 | #include <sdmod.hxx> | |||
58 | #include <sdpage.hxx> | |||
59 | #include <drawdoc.hxx> | |||
60 | #include <stlpool.hxx> | |||
61 | #include <sdxfer.hxx> | |||
62 | #include <unomodel.hxx> | |||
63 | #include <vcl/virdev.hxx> | |||
64 | #include <vcl/svapp.hxx> | |||
65 | ||||
66 | using namespace ::com::sun::star; | |||
67 | using namespace ::com::sun::star::lang; | |||
68 | using namespace ::com::sun::star::uno; | |||
69 | using namespace ::com::sun::star::io; | |||
70 | using namespace ::com::sun::star::datatransfer; | |||
71 | using namespace ::com::sun::star::datatransfer::clipboard; | |||
72 | ||||
73 | constexpr sal_uInt32 SDTRANSFER_OBJECTTYPE_DRAWMODEL = 1; | |||
74 | constexpr sal_uInt32 SDTRANSFER_OBJECTTYPE_DRAWOLE = 2; | |||
75 | ||||
76 | SdTransferable::SdTransferable( SdDrawDocument* pSrcDoc, ::sd::View* pWorkView, bool bInitOnGetData ) | |||
77 | : mpPageDocShell( nullptr ) | |||
78 | , mpSdView( pWorkView ) | |||
79 | , mpSdViewIntern( pWorkView ) | |||
80 | , mpSdDrawDocument( nullptr ) | |||
81 | , mpSdDrawDocumentIntern( nullptr ) | |||
82 | , mpSourceDoc( pSrcDoc ) | |||
83 | , mpVDev( nullptr ) | |||
84 | , mbInternalMove( false ) | |||
85 | , mbOwnDocument( false ) | |||
86 | , mbOwnView( false ) | |||
87 | , mbLateInit( bInitOnGetData ) | |||
88 | , mbPageTransferable( false ) | |||
89 | , mbPageTransferablePersistent( false ) | |||
90 | , maUserData() | |||
91 | { | |||
92 | if( mpSourceDoc ) | |||
93 | StartListening( *mpSourceDoc ); | |||
94 | ||||
95 | if( pWorkView ) | |||
96 | StartListening( *pWorkView ); | |||
97 | ||||
98 | if( !mbLateInit ) | |||
99 | CreateData(); | |||
100 | } | |||
101 | ||||
102 | SdTransferable::~SdTransferable() | |||
103 | { | |||
104 | SolarMutexGuard g; | |||
105 | ||||
106 | if( mpSourceDoc ) | |||
107 | EndListening( *mpSourceDoc ); | |||
108 | ||||
109 | if( mpSdView ) | |||
110 | EndListening( *const_cast< sd::View *>( mpSdView) ); | |||
111 | ||||
112 | ObjectReleased(); | |||
113 | ||||
114 | if( mbOwnView ) | |||
115 | delete mpSdViewIntern; | |||
116 | ||||
117 | mpOLEDataHelper.reset(); | |||
118 | ||||
119 | if( maDocShellRef.is() ) | |||
120 | { | |||
121 | SfxObjectShell* pObj = maDocShellRef.get(); | |||
122 | ::sd::DrawDocShell* pDocSh = static_cast< ::sd::DrawDocShell*>(pObj); | |||
123 | pDocSh->DoClose(); | |||
124 | } | |||
125 | ||||
126 | maDocShellRef.clear(); | |||
127 | ||||
128 | if( mbOwnDocument ) | |||
129 | delete mpSdDrawDocumentIntern; | |||
130 | ||||
131 | mpGraphic.reset(); | |||
132 | mpBookmark.reset(); | |||
133 | mpImageMap.reset(); | |||
134 | ||||
135 | mpVDev.disposeAndClear(); | |||
136 | mpObjDesc.reset(); | |||
137 | ||||
138 | //call explicitly at end of dtor to be covered by above SolarMutex | |||
139 | maUserData.clear(); | |||
140 | } | |||
141 | ||||
142 | void SdTransferable::CreateObjectReplacement( SdrObject* pObj ) | |||
143 | { | |||
144 | if( !pObj ) | |||
145 | return; | |||
146 | ||||
147 | mpOLEDataHelper.reset(); | |||
148 | mpGraphic.reset(); | |||
149 | mpBookmark.reset(); | |||
150 | mpImageMap.reset(); | |||
151 | ||||
152 | if( nullptr!= dynamic_cast< const SdrOle2Obj* >( pObj ) ) | |||
153 | { | |||
154 | try | |||
155 | { | |||
156 | uno::Reference < embed::XEmbeddedObject > xObj = static_cast< SdrOle2Obj* >( pObj )->GetObjRef(); | |||
157 | uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); | |||
158 | if( xObj.is() && xPersist.is() && xPersist->hasEntry() ) | |||
159 | { | |||
160 | mpOLEDataHelper.reset( new TransferableDataHelper( new SvEmbedTransferHelper( xObj, static_cast< SdrOle2Obj* >( pObj )->GetGraphic(), static_cast< SdrOle2Obj* >( pObj )->GetAspect() ) ) ); | |||
161 | ||||
162 | // TODO/LATER: the standalone handling of the graphic should not be used any more in future | |||
163 | // The EmbedDataHelper should bring the graphic in future | |||
164 | const Graphic* pObjGr = static_cast< SdrOle2Obj* >( pObj )->GetGraphic(); | |||
165 | if ( pObjGr ) | |||
166 | mpGraphic.reset( new Graphic( *pObjGr ) ); | |||
167 | } | |||
168 | } | |||
169 | catch( uno::Exception& ) | |||
170 | {} | |||
171 | } | |||
172 | else if( dynamic_cast< const SdrGrafObj *>( pObj ) != nullptr && (mpSourceDoc && !SdDrawDocument::GetAnimationInfo( pObj )) ) | |||
173 | { | |||
174 | mpGraphic.reset( new Graphic( static_cast< SdrGrafObj* >( pObj )->GetTransformedGraphic() ) ); | |||
175 | } | |||
176 | else if( pObj->IsUnoObj() && SdrInventor::FmForm == pObj->GetObjInventor() && ( pObj->GetObjIdentifier() == sal_uInt16(OBJ_FM_BUTTON) ) ) | |||
177 | { | |||
178 | SdrUnoObj* pUnoCtrl = static_cast< SdrUnoObj* >( pObj ); | |||
179 | ||||
180 | if (SdrInventor::FmForm == pUnoCtrl->GetObjInventor()) | |||
181 | { | |||
182 | const Reference< css::awt::XControlModel >& xControlModel( pUnoCtrl->GetUnoControlModel() ); | |||
183 | ||||
184 | if( !xControlModel.is() ) | |||
185 | return; | |||
186 | ||||
187 | Reference< css::beans::XPropertySet > xPropSet( xControlModel, UNO_QUERY ); | |||
188 | ||||
189 | if( !xPropSet.is() ) | |||
190 | return; | |||
191 | ||||
192 | css::form::FormButtonType eButtonType; | |||
193 | Any aTmp( xPropSet->getPropertyValue( "ButtonType" ) ); | |||
194 | ||||
195 | if( aTmp >>= eButtonType ) | |||
196 | { | |||
197 | OUString aLabel, aURL; | |||
198 | ||||
199 | xPropSet->getPropertyValue( "Label" ) >>= aLabel; | |||
200 | xPropSet->getPropertyValue( "TargetURL" ) >>= aURL; | |||
201 | ||||
202 | mpBookmark.reset( new INetBookmark( aURL, aLabel ) ); | |||
203 | } | |||
204 | } | |||
205 | } | |||
206 | else if( dynamic_cast< const SdrTextObj *>( pObj ) != nullptr ) | |||
207 | { | |||
208 | const OutlinerParaObject* pPara; | |||
209 | ||||
210 | if( (pPara = static_cast< SdrTextObj* >( pObj )->GetOutlinerParaObject()) != nullptr ) | |||
211 | { | |||
212 | const SvxFieldItem* pField; | |||
213 | ||||
214 | if( (pField = pPara->GetTextObject().GetField()) != nullptr ) | |||
215 | { | |||
216 | const SvxFieldData* pData = pField->GetField(); | |||
217 | ||||
218 | if( auto pURL = dynamic_cast< const SvxURLField *>( pData ) ) | |||
219 | { | |||
220 | // #i63399# This special code identifies TextFrames which have just a URL | |||
221 | // as content and directly add this to the clipboard, probably to avoid adding | |||
222 | // an unnecessary DrawObject to the target where paste may take place. This is | |||
223 | // wanted only for SdrObjects with no fill and no line, else it is necessary to | |||
224 | // use the whole SdrObject. Test here for Line/FillStyle and take shortcut only | |||
225 | // when both are unused | |||
226 | if(!pObj->HasFillStyle() && !pObj->HasLineStyle()) | |||
227 | { | |||
228 | mpBookmark.reset( new INetBookmark( pURL->GetURL(), pURL->GetRepresentation() ) ); | |||
229 | } | |||
230 | } | |||
231 | } | |||
232 | } | |||
233 | } | |||
234 | ||||
235 | SvxIMapInfo* pInfo = SvxIMapInfo::GetIMapInfo( pObj ); | |||
236 | ||||
237 | if( pInfo ) | |||
238 | mpImageMap.reset( new ImageMap( pInfo->GetImageMap() ) ); | |||
239 | } | |||
240 | ||||
241 | void SdTransferable::CreateData() | |||
242 | { | |||
243 | if( mpSdDrawDocument && !mpSdViewIntern ) | |||
244 | { | |||
245 | mbOwnView = true; | |||
246 | ||||
247 | SdPage* pPage = mpSdDrawDocument->GetSdPage(0, PageKind::Standard); | |||
248 | ||||
249 | if( pPage && 1 == pPage->GetObjCount() ) | |||
250 | CreateObjectReplacement( pPage->GetObj( 0 ) ); | |||
251 | ||||
252 | mpVDev = VclPtr<VirtualDevice>::Create( *Application::GetDefaultDevice() ); | |||
253 | mpVDev->SetMapMode( MapMode( mpSdDrawDocumentIntern->GetScaleUnit(), Point(), mpSdDrawDocumentIntern->GetScaleFraction(), mpSdDrawDocumentIntern->GetScaleFraction() ) ); | |||
254 | mpSdViewIntern = new ::sd::View( *mpSdDrawDocumentIntern, mpVDev ); | |||
255 | mpSdViewIntern->EndListening(*mpSdDrawDocumentIntern ); | |||
256 | mpSdViewIntern->hideMarkHandles(); | |||
257 | SdrPageView* pPageView = mpSdViewIntern->ShowSdrPage(pPage); | |||
258 | mpSdViewIntern->MarkAllObj(pPageView); | |||
259 | } | |||
260 | else if( mpSdView && !mpSdDrawDocumentIntern ) | |||
261 | { | |||
262 | const SdrMarkList& rMarkList = mpSdView->GetMarkedObjectList(); | |||
263 | ||||
264 | if( rMarkList.GetMarkCount() == 1 ) | |||
265 | CreateObjectReplacement( rMarkList.GetMark( 0 )->GetMarkedSdrObj() ); | |||
266 | ||||
267 | if( mpSourceDoc ) | |||
268 | mpSourceDoc->CreatingDataObj(this); | |||
269 | mpSdDrawDocumentIntern = static_cast<SdDrawDocument*>( mpSdView->CreateMarkedObjModel().release() ); | |||
270 | if( mpSourceDoc ) | |||
271 | mpSourceDoc->CreatingDataObj(nullptr); | |||
272 | ||||
273 | if( !maDocShellRef.is() && mpSdDrawDocumentIntern->GetDocSh() ) | |||
274 | maDocShellRef = mpSdDrawDocumentIntern->GetDocSh(); | |||
275 | ||||
276 | if( !maDocShellRef.is() ) | |||
277 | { | |||
278 | OSL_FAIL( "SdTransferable::CreateData(), failed to create a model with persist, clipboard operation will fail for OLE objects!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sd/source/ui/app/sdxfer.cxx" ":" "278" ": "), "%s", "SdTransferable::CreateData(), failed to create a model with persist, clipboard operation will fail for OLE objects!" ); } } while (false); | |||
279 | mbOwnDocument = true; | |||
280 | } | |||
281 | ||||
282 | // Use dimension of source page | |||
283 | SdrPageView* pPgView = mpSdView->GetSdrPageView(); | |||
284 | SdPage* pOldPage = static_cast<SdPage*>( pPgView->GetPage() ); | |||
285 | SdrModel* pOldModel = mpSdView->GetModel(); | |||
286 | SdStyleSheetPool* pOldStylePool = static_cast<SdStyleSheetPool*>( pOldModel->GetStyleSheetPool() ); | |||
287 | SdStyleSheetPool* pNewStylePool = static_cast<SdStyleSheetPool*>( mpSdDrawDocumentIntern->GetStyleSheetPool() ); | |||
288 | SdPage* pPage = mpSdDrawDocumentIntern->GetSdPage( 0, PageKind::Standard ); | |||
289 | OUString aOldLayoutName( pOldPage->GetLayoutName() ); | |||
290 | ||||
291 | pPage->SetSize( pOldPage->GetSize() ); | |||
292 | pPage->SetLayoutName( aOldLayoutName ); | |||
293 | pNewStylePool->CopyGraphicSheets( *pOldStylePool ); | |||
294 | pNewStylePool->CopyCellSheets( *pOldStylePool ); | |||
295 | pNewStylePool->CopyTableStyles( *pOldStylePool ); | |||
296 | sal_Int32 nPos = aOldLayoutName.indexOf( SD_LT_SEPARATOR"~LT~" ); | |||
297 | if( nPos != -1 ) | |||
298 | aOldLayoutName = aOldLayoutName.copy( 0, nPos ); | |||
299 | StyleSheetCopyResultVector aCreatedSheets; | |||
300 | pNewStylePool->CopyLayoutSheets( aOldLayoutName, *pOldStylePool, aCreatedSheets ); | |||
301 | } | |||
302 | ||||
303 | // set VisArea and adjust objects if necessary | |||
304 | if( !(maVisArea.IsEmpty() && | |||
305 | mpSdDrawDocumentIntern && mpSdViewIntern && | |||
306 | mpSdDrawDocumentIntern->GetPageCount()) ) | |||
307 | return; | |||
308 | ||||
309 | SdPage* pPage = mpSdDrawDocumentIntern->GetSdPage( 0, PageKind::Standard ); | |||
310 | ||||
311 | if( 1 == mpSdDrawDocumentIntern->GetPageCount() ) | |||
312 | { | |||
313 | // #112978# need to use GetAllMarkedBoundRect instead of GetAllMarkedRect to get | |||
314 | // fat lines correctly | |||
315 | maVisArea = mpSdViewIntern->GetAllMarkedBoundRect(); | |||
316 | Point aOrigin( maVisArea.TopLeft() ); | |||
317 | Size aVector( -aOrigin.X(), -aOrigin.Y() ); | |||
318 | ||||
319 | for( size_t nObj = 0, nObjCount = pPage->GetObjCount(); nObj < nObjCount; ++nObj ) | |||
320 | { | |||
321 | SdrObject* pObj = pPage->GetObj( nObj ); | |||
322 | pObj->NbcMove( aVector ); | |||
323 | } | |||
324 | } | |||
325 | else | |||
326 | maVisArea.SetSize( pPage->GetSize() ); | |||
327 | ||||
328 | // output is at the zero point | |||
329 | maVisArea.SetPos( Point() ); | |||
330 | } | |||
331 | ||||
332 | static bool lcl_HasOnlyControls( SdrModel* pModel ) | |||
333 | { | |||
334 | bool bOnlyControls = false; // default if there are no objects | |||
335 | ||||
336 | if ( pModel ) | |||
337 | { | |||
338 | SdrPage* pPage = pModel->GetPage(0); | |||
339 | if (pPage) | |||
340 | { | |||
341 | SdrObjListIter aIter( pPage, SdrIterMode::DeepNoGroups ); | |||
342 | SdrObject* pObj = aIter.Next(); | |||
343 | if ( pObj ) | |||
344 | { | |||
345 | bOnlyControls = true; // only set if there are any objects at all | |||
346 | while ( pObj ) | |||
347 | { | |||
348 | if (dynamic_cast< const SdrUnoObj *>( pObj ) == nullptr) | |||
349 | { | |||
350 | bOnlyControls = false; | |||
351 | break; | |||
352 | } | |||
353 | pObj = aIter.Next(); | |||
354 | } | |||
355 | } | |||
356 | } | |||
357 | } | |||
358 | ||||
359 | return bOnlyControls; | |||
360 | } | |||
361 | ||||
362 | static bool lcl_HasOnlyOneTable( SdrModel* pModel ) | |||
363 | { | |||
364 | if ( pModel ) | |||
365 | { | |||
366 | SdrPage* pPage = pModel->GetPage(0); | |||
367 | if (pPage && pPage->GetObjCount() == 1 ) | |||
368 | { | |||
369 | if( dynamic_cast< sdr::table::SdrTableObj* >( pPage->GetObj(0) ) != nullptr ) | |||
370 | return true; | |||
371 | } | |||
372 | } | |||
373 | return false; | |||
374 | } | |||
375 | ||||
376 | void SdTransferable::AddSupportedFormats() | |||
377 | { | |||
378 | if( mbPageTransferable && !mbPageTransferablePersistent ) | |||
379 | return; | |||
380 | ||||
381 | if( !mbLateInit ) | |||
382 | CreateData(); | |||
383 | ||||
384 | if( mpObjDesc ) | |||
385 | AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ); | |||
386 | ||||
387 | if( mpOLEDataHelper ) | |||
388 | { | |||
389 | AddFormat( SotClipboardFormatId::EMBED_SOURCE ); | |||
390 | ||||
391 | DataFlavorExVector aVector( mpOLEDataHelper->GetDataFlavorExVector() ); | |||
392 | ||||
393 | for( const auto& rItem : aVector ) | |||
394 | AddFormat( rItem ); | |||
395 | } | |||
396 | else if( mpGraphic ) | |||
397 | { | |||
398 | // #i25616# | |||
399 | AddFormat( SotClipboardFormatId::DRAWING ); | |||
400 | ||||
401 | AddFormat( SotClipboardFormatId::SVXB ); | |||
402 | ||||
403 | if( mpGraphic->GetType() == GraphicType::Bitmap ) | |||
404 | { | |||
405 | AddFormat( SotClipboardFormatId::PNG ); | |||
406 | AddFormat( SotClipboardFormatId::BITMAP ); | |||
407 | AddFormat( SotClipboardFormatId::GDIMETAFILE ); | |||
408 | } | |||
409 | else | |||
410 | { | |||
411 | AddFormat( SotClipboardFormatId::GDIMETAFILE ); | |||
412 | AddFormat( SotClipboardFormatId::PNG ); | |||
413 | AddFormat( SotClipboardFormatId::BITMAP ); | |||
414 | } | |||
415 | } | |||
416 | else if( mpBookmark ) | |||
417 | { | |||
418 | AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK ); | |||
419 | AddFormat( SotClipboardFormatId::STRING ); | |||
420 | } | |||
421 | else | |||
422 | { | |||
423 | AddFormat( SotClipboardFormatId::EMBED_SOURCE ); | |||
424 | AddFormat( SotClipboardFormatId::DRAWING ); | |||
425 | if( !mpSdDrawDocument || !lcl_HasOnlyControls( mpSdDrawDocument ) ) | |||
426 | { | |||
427 | AddFormat( SotClipboardFormatId::GDIMETAFILE ); | |||
428 | AddFormat( SotClipboardFormatId::PNG ); | |||
429 | AddFormat( SotClipboardFormatId::BITMAP ); | |||
430 | } | |||
431 | ||||
432 | if( lcl_HasOnlyOneTable( mpSdDrawDocument ) ) { | |||
433 | AddFormat( SotClipboardFormatId::RTF ); | |||
434 | AddFormat( SotClipboardFormatId::RICHTEXT ); | |||
435 | } | |||
436 | } | |||
437 | ||||
438 | if( mpImageMap ) | |||
439 | AddFormat( SotClipboardFormatId::SVIM ); | |||
440 | } | |||
441 | ||||
442 | bool SdTransferable::GetData( const DataFlavor& rFlavor, const OUString& rDestDoc ) | |||
443 | { | |||
444 | if (SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule ::Draw)) )==nullptr) | |||
| ||||
445 | return false; | |||
446 | ||||
447 | SotClipboardFormatId nFormat = SotExchange::GetFormat( rFlavor ); | |||
448 | bool bOK = false; | |||
449 | ||||
450 | CreateData(); | |||
451 | ||||
452 | if( nFormat == SotClipboardFormatId::RTF && lcl_HasOnlyOneTable( mpSdDrawDocument ) ) | |||
453 | { | |||
454 | bOK = SetTableRTF( mpSdDrawDocument ); | |||
455 | } | |||
456 | else if( mpOLEDataHelper && mpOLEDataHelper->HasFormat( rFlavor ) ) | |||
457 | { | |||
458 | // TODO/LATER: support all the graphical formats, the embedded object scenario should not have separated handling | |||
459 | if( nFormat == SotClipboardFormatId::GDIMETAFILE && mpGraphic ) | |||
460 | bOK = SetGDIMetaFile( mpGraphic->GetGDIMetaFile() ); | |||
461 | else | |||
462 | bOK = SetAny( mpOLEDataHelper->GetAny(rFlavor, rDestDoc) ); | |||
463 | } | |||
464 | else if( HasFormat( nFormat ) ) | |||
465 | { | |||
466 | if( ( nFormat == SotClipboardFormatId::LINKSRCDESCRIPTOR || nFormat == SotClipboardFormatId::OBJECTDESCRIPTOR ) && mpObjDesc ) | |||
467 | { | |||
468 | bOK = SetTransferableObjectDescriptor( *mpObjDesc ); | |||
469 | } | |||
470 | else if( nFormat == SotClipboardFormatId::DRAWING ) | |||
471 | { | |||
472 | SfxObjectShellRef aOldRef( maDocShellRef ); | |||
473 | ||||
474 | maDocShellRef.clear(); | |||
475 | ||||
476 | if( mpSdViewIntern ) | |||
477 | { | |||
478 | SdDrawDocument& rInternDoc = mpSdViewIntern->GetDoc(); | |||
479 | rInternDoc.CreatingDataObj(this); | |||
480 | SdDrawDocument* pDoc = dynamic_cast< SdDrawDocument* >( mpSdViewIntern->CreateMarkedObjModel().release() ); | |||
481 | rInternDoc.CreatingDataObj(nullptr); | |||
482 | ||||
483 | bOK = SetObject( pDoc, SDTRANSFER_OBJECTTYPE_DRAWMODEL, rFlavor ); | |||
484 | ||||
485 | if( maDocShellRef.is() ) | |||
486 | { | |||
487 | maDocShellRef->DoClose(); | |||
488 | } | |||
489 | else | |||
490 | { | |||
491 | delete pDoc; | |||
492 | } | |||
493 | } | |||
494 | ||||
495 | maDocShellRef = aOldRef; | |||
496 | } | |||
497 | else if( nFormat == SotClipboardFormatId::GDIMETAFILE ) | |||
498 | { | |||
499 | if (mpSdViewIntern) | |||
500 | { | |||
501 | const bool bToggleOnlineSpell = mpSdDrawDocumentIntern && mpSdDrawDocumentIntern->GetOnlineSpell(); | |||
502 | if (bToggleOnlineSpell) | |||
503 | mpSdDrawDocumentIntern->SetOnlineSpell(false); | |||
504 | bOK = SetGDIMetaFile( mpSdViewIntern->GetMarkedObjMetaFile( true ) ); | |||
505 | if (bToggleOnlineSpell) | |||
506 | mpSdDrawDocumentIntern->SetOnlineSpell(true); | |||
507 | } | |||
508 | } | |||
509 | else if( SotClipboardFormatId::BITMAP == nFormat || SotClipboardFormatId::PNG == nFormat ) | |||
510 | { | |||
511 | if (mpSdViewIntern) | |||
512 | { | |||
513 | const bool bToggleOnlineSpell = mpSdDrawDocumentIntern && mpSdDrawDocumentIntern->GetOnlineSpell(); | |||
514 | if (bToggleOnlineSpell) | |||
515 | mpSdDrawDocumentIntern->SetOnlineSpell(false); | |||
516 | bOK = SetBitmapEx( mpSdViewIntern->GetMarkedObjBitmapEx(true), rFlavor ); | |||
517 | if (bToggleOnlineSpell) | |||
518 | mpSdDrawDocumentIntern->SetOnlineSpell(true); | |||
519 | } | |||
520 | } | |||
521 | else if( ( nFormat == SotClipboardFormatId::STRING ) && mpBookmark ) | |||
522 | { | |||
523 | bOK = SetString( mpBookmark->GetURL(), rFlavor ); | |||
524 | } | |||
525 | else if( ( nFormat == SotClipboardFormatId::SVXB ) && mpGraphic ) | |||
526 | { | |||
527 | bOK = SetGraphic( *mpGraphic ); | |||
528 | } | |||
529 | else if( ( nFormat == SotClipboardFormatId::SVIM ) && mpImageMap ) | |||
530 | { | |||
531 | bOK = SetImageMap( *mpImageMap ); | |||
532 | } | |||
533 | else if( mpBookmark ) | |||
534 | { | |||
535 | bOK = SetINetBookmark( *mpBookmark, rFlavor ); | |||
536 | } | |||
537 | else if( nFormat == SotClipboardFormatId::EMBED_SOURCE ) | |||
538 | { | |||
539 | if( mpSdDrawDocumentIntern ) | |||
540 | { | |||
541 | if( !maDocShellRef.is() ) | |||
542 | { | |||
543 | maDocShellRef = new ::sd::DrawDocShell( | |||
544 | mpSdDrawDocumentIntern, | |||
545 | SfxObjectCreateMode::EMBEDDED, | |||
546 | true, | |||
547 | mpSdDrawDocumentIntern->GetDocumentType()); | |||
548 | mbOwnDocument = false; | |||
549 | maDocShellRef->DoInitNew(); | |||
550 | } | |||
551 | ||||
552 | maDocShellRef->SetVisArea( maVisArea ); | |||
553 | bOK = SetObject( maDocShellRef.get(), SDTRANSFER_OBJECTTYPE_DRAWOLE, rFlavor ); | |||
554 | } | |||
555 | } | |||
556 | } | |||
557 | ||||
558 | return bOK; | |||
559 | } | |||
560 | ||||
561 | bool SdTransferable::WriteObject( tools::SvRef<SotStorageStream>& rxOStm, void* pObject, sal_uInt32 nObjectType, const DataFlavor& ) | |||
562 | { | |||
563 | bool bRet = false; | |||
564 | ||||
565 | switch( nObjectType ) | |||
566 | { | |||
567 | case SDTRANSFER_OBJECTTYPE_DRAWMODEL: | |||
568 | { | |||
569 | try | |||
570 | { | |||
571 | static const bool bDontBurnInStyleSheet = ( getenv( "AVOID_BURN_IN_FOR_GALLERY_THEME" ) != nullptr ); | |||
572 | SdDrawDocument* pDoc = static_cast<SdDrawDocument*>(pObject); | |||
573 | if ( !bDontBurnInStyleSheet ) | |||
574 | pDoc->BurnInStyleSheetAttributes(); | |||
575 | rxOStm->SetBufferSize( 16348 ); | |||
576 | ||||
577 | Reference< XComponent > xComponent( new SdXImpressDocument( pDoc, true ) ); | |||
578 | pDoc->setUnoModel( Reference< XInterface >::query( xComponent ) ); | |||
579 | ||||
580 | { | |||
581 | css::uno::Reference<css::io::XOutputStream> xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) ); | |||
582 | if( SvxDrawingLayerExport( pDoc, xDocOut, xComponent, (pDoc->GetDocumentType() == DocumentType::Impress) ? "com.sun.star.comp.Impress.XMLClipboardExporter" : "com.sun.star.comp.DrawingLayer.XMLExporter" ) ) | |||
583 | rxOStm->Commit(); | |||
584 | } | |||
585 | ||||
586 | xComponent->dispose(); | |||
587 | bRet = ( rxOStm->GetError() == ERRCODE_NONEErrCode(0) ); | |||
588 | } | |||
589 | catch( Exception& ) | |||
590 | { | |||
591 | OSL_FAIL( "sd::SdTransferable::WriteObject(), exception caught!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sd/source/ui/app/sdxfer.cxx" ":" "591" ": "), "%s", "sd::SdTransferable::WriteObject(), exception caught!" ); } } while (false); | |||
592 | bRet = false; | |||
593 | } | |||
594 | } | |||
595 | break; | |||
596 | ||||
597 | case SDTRANSFER_OBJECTTYPE_DRAWOLE: | |||
598 | { | |||
599 | SfxObjectShell* pEmbObj = static_cast<SfxObjectShell*>(pObject); | |||
600 | ::utl::TempFile aTempFile; | |||
601 | aTempFile.EnableKillingFile(); | |||
602 | ||||
603 | try | |||
604 | { | |||
605 | uno::Reference< embed::XStorage > xWorkStore = | |||
606 | ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE ); | |||
607 | ||||
608 | // write document storage | |||
609 | pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT6800, false ); | |||
610 | // mba: no relative URLs for clipboard! | |||
611 | SfxMedium aMedium( xWorkStore, OUString() ); | |||
612 | pEmbObj->DoSaveObjectAs( aMedium, false ); | |||
613 | pEmbObj->DoSaveCompleted(); | |||
614 | ||||
615 | uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY ); | |||
616 | if ( xTransact.is() ) | |||
617 | xTransact->commit(); | |||
618 | ||||
619 | std::unique_ptr<SvStream> pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), StreamMode::READ ); | |||
620 | if( pSrcStm ) | |||
621 | { | |||
622 | rxOStm->SetBufferSize( 0xff00 ); | |||
623 | rxOStm->WriteStream( *pSrcStm ); | |||
624 | pSrcStm.reset(); | |||
625 | } | |||
626 | ||||
627 | bRet = true; | |||
628 | rxOStm->Commit(); | |||
629 | } | |||
630 | catch ( Exception& ) | |||
631 | {} | |||
632 | } | |||
633 | ||||
634 | break; | |||
635 | ||||
636 | default: | |||
637 | break; | |||
638 | } | |||
639 | ||||
640 | return bRet; | |||
641 | } | |||
642 | ||||
643 | void SdTransferable::DragFinished( sal_Int8 nDropAction ) | |||
644 | { | |||
645 | if( mpSdView ) | |||
646 | const_cast< ::sd::View* >(mpSdView)->DragFinished( nDropAction ); | |||
647 | } | |||
648 | ||||
649 | void SdTransferable::ObjectReleased() | |||
650 | { | |||
651 | if( this == SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule ::Draw)) )->pTransferClip ) | |||
652 | SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule ::Draw)) )->pTransferClip = nullptr; | |||
653 | ||||
654 | if( this == SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule ::Draw)) )->pTransferDrag ) | |||
655 | SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule ::Draw)) )->pTransferDrag = nullptr; | |||
656 | ||||
657 | if( this == SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule ::Draw)) )->pTransferSelection ) | |||
658 | SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule ::Draw)) )->pTransferSelection = nullptr; | |||
659 | } | |||
660 | ||||
661 | void SdTransferable::SetObjectDescriptor( std::unique_ptr<TransferableObjectDescriptor> pObjDesc ) | |||
662 | { | |||
663 | mpObjDesc = std::move(pObjDesc); | |||
664 | PrepareOLE( *mpObjDesc ); | |||
665 | } | |||
666 | ||||
667 | void SdTransferable::SetPageBookmarks( const std::vector<OUString> &rPageBookmarks, bool bPersistent ) | |||
668 | { | |||
669 | if( !mpSourceDoc ) | |||
670 | return; | |||
671 | ||||
672 | if( mpSdViewIntern ) | |||
673 | mpSdViewIntern->HideSdrPage(); | |||
674 | ||||
675 | mpSdDrawDocument->ClearModel(false); | |||
676 | ||||
677 | mpPageDocShell = nullptr; | |||
678 | ||||
679 | maPageBookmarks.clear(); | |||
680 | ||||
681 | if( bPersistent ) | |||
682 | { | |||
683 | mpSdDrawDocument->CreateFirstPages(mpSourceDoc); | |||
684 | mpSdDrawDocument->InsertBookmarkAsPage( rPageBookmarks, nullptr, false, true, 1, true, | |||
685 | mpSourceDoc->GetDocSh(), true, true, false ); | |||
686 | } | |||
687 | else | |||
688 | { | |||
689 | mpPageDocShell = mpSourceDoc->GetDocSh(); | |||
690 | maPageBookmarks = rPageBookmarks; | |||
691 | } | |||
692 | ||||
693 | if( mpSdViewIntern ) | |||
694 | { | |||
695 | SdPage* pPage = mpSdDrawDocument->GetSdPage( 0, PageKind::Standard ); | |||
696 | ||||
697 | if( pPage ) | |||
698 | { | |||
699 | mpSdViewIntern->MarkAllObj( mpSdViewIntern->ShowSdrPage( pPage ) ); | |||
700 | } | |||
701 | } | |||
702 | ||||
703 | // set flags for page transferable; if ( mbPageTransferablePersistent == sal_False ), | |||
704 | // don't offer any formats => it's just for internal purposes | |||
705 | mbPageTransferable = true; | |||
706 | mbPageTransferablePersistent = bPersistent; | |||
707 | } | |||
708 | ||||
709 | sal_Int64 SAL_CALL SdTransferable::getSomething( const css::uno::Sequence< sal_Int8 >& rId ) | |||
710 | { | |||
711 | sal_Int64 nRet; | |||
712 | ||||
713 | if( isUnoTunnelId<SdTransferable>(rId) ) | |||
714 | { | |||
715 | nRet = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); | |||
716 | } | |||
717 | else | |||
718 | { | |||
719 | nRet = 0; | |||
720 | } | |||
721 | ||||
722 | return nRet; | |||
723 | } | |||
724 | ||||
725 | void SdTransferable::AddUserData (const std::shared_ptr<UserData>& rpData) | |||
726 | { | |||
727 | maUserData.push_back(rpData); | |||
728 | } | |||
729 | ||||
730 | sal_Int32 SdTransferable::GetUserDataCount() const | |||
731 | { | |||
732 | return maUserData.size(); | |||
733 | } | |||
734 | ||||
735 | std::shared_ptr<SdTransferable::UserData> SdTransferable::GetUserData (const sal_Int32 nIndex) const | |||
736 | { | |||
737 | if (nIndex>=0 && nIndex<sal_Int32(maUserData.size())) | |||
738 | return maUserData[nIndex]; | |||
739 | else | |||
740 | return std::shared_ptr<UserData>(); | |||
741 | } | |||
742 | ||||
743 | namespace | |||
744 | { | |||
745 | class theSdTransferableUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSdTransferableUnoTunnelId > {}; | |||
746 | } | |||
747 | ||||
748 | const css::uno::Sequence< sal_Int8 >& SdTransferable::getUnoTunnelId() | |||
749 | { | |||
750 | return theSdTransferableUnoTunnelId::get().getSeq(); | |||
751 | } | |||
752 | ||||
753 | SdTransferable* SdTransferable::getImplementation( const Reference< XInterface >& rxData ) throw() | |||
754 | { | |||
755 | try | |||
756 | { | |||
757 | Reference< css::lang::XUnoTunnel > xUnoTunnel( rxData, UNO_QUERY_THROW ); | |||
758 | return reinterpret_cast<SdTransferable*>(sal::static_int_cast<sal_uIntPtr>(xUnoTunnel->getSomething( SdTransferable::getUnoTunnelId()) ) ); | |||
759 | } | |||
760 | catch( const css::uno::Exception& ) | |||
761 | { | |||
762 | } | |||
763 | return nullptr; | |||
764 | } | |||
765 | ||||
766 | void SdTransferable::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) | |||
767 | { | |||
768 | if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint) | |||
769 | { | |||
770 | const SdrHint* pSdrHint = static_cast< const SdrHint* >( &rHint ); | |||
771 | if( SdrHintKind::ModelCleared == pSdrHint->GetKind() ) | |||
772 | { | |||
773 | EndListening(*mpSourceDoc); | |||
774 | mpSourceDoc = nullptr; | |||
775 | } | |||
776 | } | |||
777 | else | |||
778 | { | |||
779 | if( rHint.GetId() == SfxHintId::Dying ) | |||
780 | { | |||
781 | if( &rBC == mpSourceDoc ) | |||
782 | mpSourceDoc = nullptr; | |||
783 | if( &rBC == mpSdViewIntern ) | |||
784 | mpSdViewIntern = nullptr; | |||
785 | if( &rBC == mpSdView ) | |||
786 | mpSdView = nullptr; | |||
787 | } | |||
788 | } | |||
789 | } | |||
790 | ||||
791 | void SdTransferable::SetView(const ::sd::View* pView) | |||
792 | { | |||
793 | if (mpSdView) | |||
794 | EndListening(*const_cast<sd::View*>(mpSdView)); | |||
795 | mpSdView = pView; | |||
796 | if (mpSdView) | |||
797 | StartListening(*const_cast<sd::View*>(mpSdView)); | |||
798 | } | |||
799 | ||||
800 | bool SdTransferable::SetTableRTF( SdDrawDocument* pModel ) | |||
801 | { | |||
802 | if ( pModel ) | |||
803 | { | |||
804 | SdrPage* pPage = pModel->GetPage(0); | |||
805 | if (pPage && pPage->GetObjCount() == 1 ) | |||
806 | { | |||
807 | sdr::table::SdrTableObj* pTableObj = dynamic_cast< sdr::table::SdrTableObj* >( pPage->GetObj(0) ); | |||
808 | if( pTableObj ) | |||
809 | { | |||
810 | SvMemoryStream aMemStm( 65535, 65535 ); | |||
811 | sdr::table::ExportAsRTF( aMemStm, *pTableObj ); | |||
812 | return SetAny( Any( Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.TellEnd() ) ) ); | |||
813 | } | |||
814 | } | |||
815 | } | |||
816 | ||||
817 | return false; | |||
818 | } | |||
819 | ||||
820 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_TOOLS_REF_HXX | |||
20 | #define INCLUDED_TOOLS_REF_HXX | |||
21 | ||||
22 | #include <sal/config.h> | |||
23 | #include <cassert> | |||
24 | #include <tools/toolsdllapi.h> | |||
25 | #include <utility> | |||
26 | ||||
27 | /** | |||
28 | This implements similar functionality to boost::intrusive_ptr | |||
29 | */ | |||
30 | ||||
31 | namespace tools { | |||
32 | ||||
33 | /** T must be a class that extends SvRefBase */ | |||
34 | template<typename T> class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SvRef final { | |||
35 | public: | |||
36 | SvRef(): pObj(nullptr) {} | |||
37 | ||||
38 | SvRef(SvRef&& rObj) noexcept | |||
39 | { | |||
40 | pObj = rObj.pObj; | |||
41 | rObj.pObj = nullptr; | |||
42 | } | |||
43 | ||||
44 | SvRef(SvRef const & rObj): pObj(rObj.pObj) | |||
45 | { | |||
46 | if (pObj != nullptr) pObj->AddNextRef(); | |||
47 | } | |||
48 | ||||
49 | SvRef(T * pObjP): pObj(pObjP) | |||
50 | { | |||
51 | if (pObj != nullptr) pObj->AddFirstRef(); | |||
52 | } | |||
53 | ||||
54 | ~SvRef() | |||
55 | { | |||
56 | if (pObj != nullptr) pObj->ReleaseRef(); | |||
57 | } | |||
58 | ||||
59 | void clear() | |||
60 | { | |||
61 | if (pObj != nullptr) { | |||
62 | T * pRefObj = pObj; | |||
63 | pObj = nullptr; | |||
64 | pRefObj->ReleaseRef(); | |||
65 | } | |||
66 | } | |||
67 | ||||
68 | SvRef & operator =(SvRef const & rObj) | |||
69 | { | |||
70 | if (rObj.pObj != nullptr) { | |||
71 | rObj.pObj->AddNextRef(); | |||
| ||||
72 | } | |||
73 | T * pRefObj = pObj; | |||
74 | pObj = rObj.pObj; | |||
75 | if (pRefObj != nullptr) { | |||
76 | pRefObj->ReleaseRef(); | |||
77 | } | |||
78 | return *this; | |||
79 | } | |||
80 | ||||
81 | SvRef & operator =(SvRef && rObj) | |||
82 | { | |||
83 | if (pObj != nullptr) { | |||
84 | pObj->ReleaseRef(); | |||
85 | } | |||
86 | pObj = rObj.pObj; | |||
87 | rObj.pObj = nullptr; | |||
88 | return *this; | |||
89 | } | |||
90 | ||||
91 | bool is() const { return pObj != nullptr; } | |||
92 | ||||
93 | explicit operator bool() const { return is(); } | |||
94 | ||||
95 | T * get() const { return pObj; } | |||
96 | ||||
97 | T * operator ->() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail ("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 97, __extension__ __PRETTY_FUNCTION__)); return pObj; } | |||
98 | ||||
99 | T & operator *() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail ("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 99, __extension__ __PRETTY_FUNCTION__)); return *pObj; } | |||
100 | ||||
101 | bool operator ==(const SvRef<T> &rhs) const { return pObj == rhs.pObj; } | |||
102 | bool operator !=(const SvRef<T> &rhs) const { return !(*this == rhs); } | |||
103 | ||||
104 | private: | |||
105 | T * pObj; | |||
106 | }; | |||
107 | ||||
108 | /** | |||
109 | * This implements similar functionality to std::make_shared. | |||
110 | */ | |||
111 | template<typename T, typename... Args> | |||
112 | SvRef<T> make_ref(Args&& ... args) | |||
113 | { | |||
114 | return SvRef<T>(new T(std::forward<Args>(args)...)); | |||
115 | } | |||
116 | ||||
117 | } | |||
118 | ||||
119 | /** Classes that want to be referenced-counted via SvRef<T>, should extend this base class */ | |||
120 | class TOOLS_DLLPUBLIC__attribute__ ((visibility("default"))) SvRefBase | |||
121 | { | |||
122 | // work around a clang 3.5 optimization bug: if the bNoDelete is *first* | |||
123 | // it mis-compiles "if (--nRefCount == 0)" and never deletes any object | |||
124 | unsigned int nRefCount : 31; | |||
125 | // the only reason this is not bool is because MSVC cannot handle mixed type bitfields | |||
126 | unsigned int bNoDelete : 1; | |||
127 | ||||
128 | protected: | |||
129 | virtual ~SvRefBase() COVERITY_NOEXCEPT_FALSE; | |||
130 | ||||
131 | public: | |||
132 | SvRefBase() : nRefCount(0), bNoDelete(1) {} | |||
133 | SvRefBase(const SvRefBase &) : nRefCount(0), bNoDelete(1) {} | |||
134 | ||||
135 | SvRefBase & operator=(const SvRefBase &) { return *this; } | |||
136 | ||||
137 | void RestoreNoDelete() | |||
138 | { bNoDelete = 1; } | |||
139 | ||||
140 | void AddNextRef() | |||
141 | { | |||
142 | assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) && "Do not add refs to dead objects") ? void (0) : __assert_fail ("nRefCount < (1 << 30) && \"Do not add refs to dead objects\"" , "/home/maarten/src/libreoffice/core/include/tools/ref.hxx", 142, __extension__ __PRETTY_FUNCTION__)); | |||
143 | ++nRefCount; | |||
144 | } | |||
145 | ||||
146 | void AddFirstRef() | |||
147 | { | |||
148 | assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) && "Do not add refs to dead objects") ? void (0) : __assert_fail ("nRefCount < (1 << 30) && \"Do not add refs to dead objects\"" , "/home/maarten/src/libreoffice/core/include/tools/ref.hxx", 148, __extension__ __PRETTY_FUNCTION__)); | |||
149 | if( bNoDelete ) | |||
150 | bNoDelete = 0; | |||
151 | ++nRefCount; | |||
152 | } | |||
153 | ||||
154 | void ReleaseRef() | |||
155 | { | |||
156 | assert( nRefCount >= 1)(static_cast <bool> (nRefCount >= 1) ? void (0) : __assert_fail ("nRefCount >= 1", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 156, __extension__ __PRETTY_FUNCTION__)); | |||
157 | if( --nRefCount == 0 && !bNoDelete) | |||
158 | { | |||
159 | // I'm not sure about the original purpose of this line, but right now | |||
160 | // it serves the purpose that anything that attempts to do an AddRef() | |||
161 | // after an object is deleted will trip an assert. | |||
162 | nRefCount = 1 << 30; | |||
163 | delete this; | |||
164 | } | |||
165 | } | |||
166 | ||||
167 | unsigned int GetRefCount() const | |||
168 | { return nRefCount; } | |||
169 | }; | |||
170 | ||||
171 | template<typename T> | |||
172 | class SvCompatWeakBase; | |||
173 | ||||
174 | /** SvCompatWeakHdl acts as an intermediary between SvCompatWeakRef<T> and T. | |||
175 | */ | |||
176 | template<typename T> | |||
177 | class SvCompatWeakHdl final : public SvRefBase | |||
178 | { | |||
179 | friend class SvCompatWeakBase<T>; | |||
180 | T* _pObj; | |||
181 | ||||
182 | SvCompatWeakHdl( T* pObj ) : _pObj( pObj ) {} | |||
183 | ||||
184 | public: | |||
185 | void ResetWeakBase( ) { _pObj = nullptr; } | |||
186 | T* GetObj() { return _pObj; } | |||
187 | }; | |||
188 | ||||
189 | /** We only have one place that extends this, in include/sfx2/frame.hxx, class SfxFrame. | |||
190 | Its function is to notify the SvCompatWeakHdl when an SfxFrame object is deleted. | |||
191 | */ | |||
192 | template<typename T> | |||
193 | class SvCompatWeakBase | |||
194 | { | |||
195 | tools::SvRef< SvCompatWeakHdl<T> > _xHdl; | |||
196 | ||||
197 | public: | |||
198 | /** Does not use initializer due to compiler warnings, | |||
199 | because the lifetime of the _xHdl object can exceed the lifetime of this class. | |||
200 | */ | |||
201 | SvCompatWeakBase( T* pObj ) { _xHdl = new SvCompatWeakHdl<T>( pObj ); } | |||
202 | ||||
203 | ~SvCompatWeakBase() { _xHdl->ResetWeakBase(); } | |||
204 | ||||
205 | SvCompatWeakHdl<T>* GetHdl() { return _xHdl.get(); } | |||
206 | }; | |||
207 | ||||
208 | /** We only have one weak reference in LO, in include/sfx2/frame.hxx, class SfxFrameWeak. | |||
209 | */ | |||
210 | template<typename T> | |||
211 | class SAL_WARN_UNUSED__attribute__((warn_unused)) SvCompatWeakRef | |||
212 | { | |||
213 | tools::SvRef< SvCompatWeakHdl<T> > _xHdl; | |||
214 | public: | |||
215 | SvCompatWeakRef( ) {} | |||
216 | SvCompatWeakRef( T* pObj ) | |||
217 | { if( pObj ) _xHdl = pObj->GetHdl(); } | |||
218 | #if defined(__COVERITY__) | |||
219 | ~SvCompatWeakRef() COVERITY_NOEXCEPT_FALSE {} | |||
220 | #endif | |||
221 | SvCompatWeakRef& operator = ( T * pObj ) | |||
222 | { _xHdl = pObj ? pObj->GetHdl() : nullptr; return *this; } | |||
223 | bool is() const | |||
224 | { return _xHdl.is() && _xHdl->GetObj(); } | |||
225 | explicit operator bool() const { return is(); } | |||
226 | T* operator -> () const | |||
227 | { return _xHdl.is() ? _xHdl->GetObj() : nullptr; } | |||
228 | operator T* () const | |||
229 | { return _xHdl.is() ? _xHdl->GetObj() : nullptr; } | |||
230 | }; | |||
231 | ||||
232 | #endif | |||
233 | ||||
234 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |