File: | home/maarten/src/libreoffice/core/include/tools/ref.hxx |
Warning: | line 56, column 30 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 <com/sun/star/beans/XPropertySet.hpp> | ||||
21 | #include <com/sun/star/beans/XPropertySetInfo.hpp> | ||||
22 | #include <com/sun/star/form/FormButtonType.hpp> | ||||
23 | |||||
24 | #include <tools/urlobj.hxx> | ||||
25 | #include <sfx2/docfile.hxx> | ||||
26 | #include <svx/svdograf.hxx> | ||||
27 | #include <svx/svdouno.hxx> | ||||
28 | |||||
29 | #include <seltrans.hxx> | ||||
30 | #include <transobj.hxx> | ||||
31 | #include <drwtrans.hxx> | ||||
32 | #include <scmod.hxx> | ||||
33 | #include <dbfunc.hxx> | ||||
34 | #include <docsh.hxx> | ||||
35 | #include <drawview.hxx> | ||||
36 | #include <drwlayer.hxx> | ||||
37 | #include <markdata.hxx> | ||||
38 | |||||
39 | using namespace com::sun::star; | ||||
40 | |||||
41 | static bool lcl_IsURLButton( SdrObject* pObject ) | ||||
42 | { | ||||
43 | bool bRet = false; | ||||
44 | |||||
45 | SdrUnoObj* pUnoCtrl = dynamic_cast<SdrUnoObj*>( pObject ); | ||||
46 | if (pUnoCtrl && SdrInventor::FmForm == pUnoCtrl->GetObjInventor()) | ||||
47 | { | ||||
48 | const uno::Reference<awt::XControlModel>& xControlModel = pUnoCtrl->GetUnoControlModel(); | ||||
49 | OSL_ENSURE( xControlModel.is(), "uno control without model" )do { if (true && (!(xControlModel.is()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/app/seltrans.cxx" ":" "49" ": "), "%s", "uno control without model"); } } while (false); | ||||
50 | if ( xControlModel.is() ) | ||||
51 | { | ||||
52 | uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY ); | ||||
53 | uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo(); | ||||
54 | |||||
55 | OUString sPropButtonType( "ButtonType" ); | ||||
56 | if(xInfo->hasPropertyByName( sPropButtonType )) | ||||
57 | { | ||||
58 | uno::Any aAny = xPropSet->getPropertyValue( sPropButtonType ); | ||||
59 | form::FormButtonType eTmp; | ||||
60 | if ( (aAny >>= eTmp) && eTmp == form::FormButtonType_URL ) | ||||
61 | bRet = true; | ||||
62 | } | ||||
63 | } | ||||
64 | } | ||||
65 | |||||
66 | return bRet; | ||||
67 | } | ||||
68 | |||||
69 | ScSelectionTransferObj* ScSelectionTransferObj::CreateFromView( ScTabView* pView ) | ||||
70 | { | ||||
71 | ScSelectionTransferObj* pRet = nullptr; | ||||
72 | |||||
73 | try | ||||
74 | { | ||||
75 | if ( pView ) | ||||
76 | { | ||||
77 | ScSelectionTransferMode eMode = SC_SELTRANS_INVALID; | ||||
78 | |||||
79 | SdrView* pSdrView = pView->GetScDrawView(); | ||||
80 | if ( pSdrView ) | ||||
81 | { | ||||
82 | // handle selection on drawing layer | ||||
83 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); | ||||
84 | const size_t nMarkCount = rMarkList.GetMarkCount(); | ||||
85 | if ( nMarkCount ) | ||||
86 | { | ||||
87 | if ( nMarkCount == 1 ) | ||||
88 | { | ||||
89 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); | ||||
90 | sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier(); | ||||
91 | |||||
92 | if ( nSdrObjKind == OBJ_GRAF ) | ||||
93 | { | ||||
94 | if ( static_cast<SdrGrafObj*>(pObj)->GetGraphic().GetType() == GraphicType::Bitmap ) | ||||
95 | eMode = SC_SELTRANS_DRAW_BITMAP; | ||||
96 | else | ||||
97 | eMode = SC_SELTRANS_DRAW_GRAPHIC; | ||||
98 | } | ||||
99 | else if ( nSdrObjKind == OBJ_OLE2 ) | ||||
100 | eMode = SC_SELTRANS_DRAW_OLE; | ||||
101 | else if ( lcl_IsURLButton( pObj ) ) | ||||
102 | eMode = SC_SELTRANS_DRAW_BOOKMARK; | ||||
103 | } | ||||
104 | |||||
105 | if ( eMode == SC_SELTRANS_INVALID ) | ||||
106 | eMode = SC_SELTRANS_DRAW_OTHER; // something selected but no special selection | ||||
107 | } | ||||
108 | } | ||||
109 | if ( eMode == SC_SELTRANS_INVALID ) // no drawing object selected | ||||
110 | { | ||||
111 | ScViewData& rViewData = pView->GetViewData(); | ||||
112 | const ScMarkData& rMark = rViewData.GetMarkData(); | ||||
113 | // allow MultiMarked because GetSimpleArea may be able to merge into a simple range | ||||
114 | // (GetSimpleArea modifies a local copy of MarkData) | ||||
115 | // Also allow simple filtered area. | ||||
116 | if ( rMark.IsMarked() || rMark.IsMultiMarked() ) | ||||
117 | { | ||||
118 | ScRange aRange; | ||||
119 | ScMarkType eMarkType = rViewData.GetSimpleArea( aRange ); | ||||
120 | if (eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED) | ||||
121 | { | ||||
122 | // only for "real" selection, cursor alone isn't used | ||||
123 | if ( aRange.aStart == aRange.aEnd ) | ||||
124 | eMode = SC_SELTRANS_CELL; | ||||
125 | else | ||||
126 | eMode = SC_SELTRANS_CELLS; | ||||
127 | } | ||||
128 | } | ||||
129 | } | ||||
130 | |||||
131 | if ( eMode != SC_SELTRANS_INVALID ) | ||||
132 | pRet = new ScSelectionTransferObj( pView, eMode ); | ||||
133 | } | ||||
134 | } | ||||
135 | catch (...) | ||||
136 | { | ||||
137 | } | ||||
138 | |||||
139 | return pRet; | ||||
140 | } | ||||
141 | |||||
142 | ScSelectionTransferObj::ScSelectionTransferObj( ScTabView* pSource, ScSelectionTransferMode eNewMode ) : | ||||
143 | pView( pSource ), | ||||
144 | eMode( eNewMode ) | ||||
145 | { | ||||
146 | //! store range for StillValid | ||||
147 | } | ||||
148 | |||||
149 | ScSelectionTransferObj::~ScSelectionTransferObj() | ||||
150 | { | ||||
151 | ScModule* pScMod = SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule ::Calc)) ); | ||||
152 | if ( pScMod->GetSelectionTransfer() == this ) | ||||
153 | { | ||||
154 | // this is reached when the object wasn't really copied to the selection | ||||
155 | // (CopyToSelection has no effect under Windows) | ||||
156 | |||||
157 | ForgetView(); | ||||
158 | pScMod->SetSelectionTransfer( nullptr ); | ||||
159 | } | ||||
160 | |||||
161 | OSL_ENSURE( !pView, "ScSelectionTransferObj dtor: ForgetView not called" )do { if (true && (!(!pView))) { sal_detail_logFormat( (SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/app/seltrans.cxx" ":" "161" ": "), "%s", "ScSelectionTransferObj dtor: ForgetView not called" ); } } while (false); | ||||
162 | } | ||||
163 | |||||
164 | void ScSelectionTransferObj::ForgetView() | ||||
165 | { | ||||
166 | pView = nullptr; | ||||
167 | eMode = SC_SELTRANS_INVALID; | ||||
168 | |||||
169 | mxCellData.clear(); | ||||
170 | mxDrawData.clear(); | ||||
171 | } | ||||
172 | |||||
173 | void ScSelectionTransferObj::AddSupportedFormats() | ||||
174 | { | ||||
175 | // AddSupportedFormats must work without actually creating the | ||||
176 | // "real" transfer object | ||||
177 | |||||
178 | switch (eMode) | ||||
179 | { | ||||
180 | case SC_SELTRANS_CELL: | ||||
181 | case SC_SELTRANS_CELLS: | ||||
182 | // same formats as in ScTransferObj::AddSupportedFormats | ||||
183 | AddFormat( SotClipboardFormatId::EMBED_SOURCE ); | ||||
184 | AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ); | ||||
185 | AddFormat( SotClipboardFormatId::GDIMETAFILE ); | ||||
186 | AddFormat( SotClipboardFormatId::PNG ); | ||||
187 | AddFormat( SotClipboardFormatId::BITMAP ); | ||||
188 | AddFormat( SotClipboardFormatId::HTML ); | ||||
189 | AddFormat( SotClipboardFormatId::SYLK ); | ||||
190 | AddFormat( SotClipboardFormatId::LINK ); | ||||
191 | AddFormat( SotClipboardFormatId::DIF ); | ||||
192 | AddFormat( SotClipboardFormatId::STRING ); | ||||
193 | AddFormat( SotClipboardFormatId::STRING_TSVC ); | ||||
194 | AddFormat( SotClipboardFormatId::RTF ); | ||||
195 | AddFormat( SotClipboardFormatId::RICHTEXT ); | ||||
196 | if ( eMode == SC_SELTRANS_CELL ) | ||||
197 | { | ||||
198 | AddFormat( SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT ); | ||||
199 | } | ||||
200 | break; | ||||
201 | |||||
202 | // different graphic formats as in ScDrawTransferObj::AddSupportedFormats: | ||||
203 | |||||
204 | case SC_SELTRANS_DRAW_BITMAP: | ||||
205 | AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ); | ||||
206 | AddFormat( SotClipboardFormatId::SVXB ); | ||||
207 | AddFormat( SotClipboardFormatId::PNG ); | ||||
208 | AddFormat( SotClipboardFormatId::BITMAP ); | ||||
209 | AddFormat( SotClipboardFormatId::GDIMETAFILE ); | ||||
210 | break; | ||||
211 | |||||
212 | case SC_SELTRANS_DRAW_GRAPHIC: | ||||
213 | AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ); | ||||
214 | AddFormat( SotClipboardFormatId::SVXB ); | ||||
215 | AddFormat( SotClipboardFormatId::GDIMETAFILE ); | ||||
216 | AddFormat( SotClipboardFormatId::PNG ); | ||||
217 | AddFormat( SotClipboardFormatId::BITMAP ); | ||||
218 | break; | ||||
219 | |||||
220 | case SC_SELTRANS_DRAW_BOOKMARK: | ||||
221 | AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ); | ||||
222 | AddFormat( SotClipboardFormatId::SOLK ); | ||||
223 | AddFormat( SotClipboardFormatId::STRING ); | ||||
224 | AddFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR ); | ||||
225 | AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK ); | ||||
226 | AddFormat( SotClipboardFormatId::DRAWING ); | ||||
227 | break; | ||||
228 | |||||
229 | case SC_SELTRANS_DRAW_OLE: | ||||
230 | AddFormat( SotClipboardFormatId::EMBED_SOURCE ); | ||||
231 | AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ); | ||||
232 | AddFormat( SotClipboardFormatId::GDIMETAFILE ); | ||||
233 | break; | ||||
234 | |||||
235 | case SC_SELTRANS_DRAW_OTHER: | ||||
236 | // other drawing objects | ||||
237 | AddFormat( SotClipboardFormatId::EMBED_SOURCE ); | ||||
238 | AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ); | ||||
239 | AddFormat( SotClipboardFormatId::DRAWING ); | ||||
240 | AddFormat( SotClipboardFormatId::PNG ); | ||||
241 | AddFormat( SotClipboardFormatId::BITMAP ); | ||||
242 | AddFormat( SotClipboardFormatId::GDIMETAFILE ); | ||||
243 | break; | ||||
244 | |||||
245 | default: | ||||
246 | { | ||||
247 | // added to avoid warnings | ||||
248 | } | ||||
249 | } | ||||
250 | } | ||||
251 | |||||
252 | void ScSelectionTransferObj::CreateCellData() | ||||
253 | { | ||||
254 | OSL_ENSURE( !mxCellData.is(), "CreateCellData twice" )do { if (true && (!(!mxCellData.is()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/app/seltrans.cxx" ":" "254" ": "), "%s", "CreateCellData twice"); } } while (false ); | ||||
255 | if ( pView ) | ||||
256 | { | ||||
257 | ScViewData& rViewData = pView->GetViewData(); | ||||
258 | ScMarkData aNewMark( rViewData.GetMarkData() ); // use local copy for MarkToSimple | ||||
259 | aNewMark.MarkToSimple(); | ||||
260 | |||||
261 | // similar to ScViewFunctionSet::BeginDrag | ||||
262 | if ( aNewMark.IsMarked() && !aNewMark.IsMultiMarked() ) | ||||
263 | { | ||||
264 | ScDocShell* pDocSh = rViewData.GetDocShell(); | ||||
265 | |||||
266 | ScRange aSelRange; | ||||
267 | aNewMark.GetMarkArea( aSelRange ); | ||||
268 | ScDocShellRef aDragShellRef; | ||||
269 | if ( pDocSh->GetDocument().HasOLEObjectsInArea( aSelRange, &aNewMark ) ) | ||||
270 | { | ||||
271 | aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately | ||||
272 | aDragShellRef->DoInitNew(); | ||||
273 | } | ||||
274 | ScDrawLayer::SetGlobalDrawPersist( aDragShellRef.get() ); | ||||
275 | |||||
276 | ScDocumentUniquePtr pClipDoc(new ScDocument( SCDOCMODE_CLIP )); | ||||
277 | // bApi = sal_True -> no error messages | ||||
278 | // #i18364# bStopEdit = sal_False -> don't end edit mode | ||||
279 | // (this may be called from pasting into the edit line) | ||||
280 | bool bCopied = rViewData.GetView()->CopyToClip( pClipDoc.get(), false, true, true, false ); | ||||
281 | |||||
282 | ScDrawLayer::SetGlobalDrawPersist(nullptr); | ||||
283 | |||||
284 | if ( bCopied ) | ||||
285 | { | ||||
286 | TransferableObjectDescriptor aObjDesc; | ||||
287 | pDocSh->FillTransferableObjectDescriptor( aObjDesc ); | ||||
288 | aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); | ||||
289 | // maSize is set in ScTransferObj ctor | ||||
290 | |||||
291 | rtl::Reference<ScTransferObj> pTransferObj = new ScTransferObj( std::move(pClipDoc), aObjDesc ); | ||||
292 | |||||
293 | // SetDragHandlePos is not used - there is no mouse position | ||||
294 | //? pTransferObj->SetVisibleTab( nTab ); | ||||
295 | |||||
296 | SfxObjectShellRef aPersistRef( aDragShellRef.get() ); | ||||
297 | pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive | ||||
298 | |||||
299 | pTransferObj->SetDragSource( pDocSh, aNewMark ); | ||||
300 | |||||
301 | mxCellData = pTransferObj; | ||||
302 | } | ||||
303 | } | ||||
304 | } | ||||
305 | OSL_ENSURE( mxCellData.is(), "can't create CellData" )do { if (true && (!(mxCellData.is()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/app/seltrans.cxx" ":" "305" ": "), "%s", "can't create CellData"); } } while ( false); | ||||
306 | } | ||||
307 | |||||
308 | void ScSelectionTransferObj::CreateDrawData() | ||||
309 | { | ||||
310 | OSL_ENSURE( !mxDrawData.is(), "CreateDrawData twice" )do { if (true && (!(!mxDrawData.is()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/app/seltrans.cxx" ":" "310" ": "), "%s", "CreateDrawData twice"); } } while (false ); | ||||
311 | if ( pView ) | ||||
312 | { | ||||
313 | // similar to ScDrawView::BeginDrag | ||||
314 | |||||
315 | ScDrawView* pDrawView = pView->GetScDrawView(); | ||||
316 | if ( pDrawView ) | ||||
317 | { | ||||
318 | bool bAnyOle, bOneOle; | ||||
319 | const SdrMarkList& rMarkList = pDrawView->GetMarkedObjectList(); | ||||
320 | ScDrawView::CheckOle( rMarkList, bAnyOle, bOneOle ); | ||||
321 | |||||
322 | ScDocShellRef aDragShellRef; | ||||
323 | if (bAnyOle) | ||||
324 | { | ||||
325 | aDragShellRef = new ScDocShell; // Without Ref the DocShell does not live | ||||
326 | aDragShellRef->DoInitNew(); | ||||
327 | } | ||||
328 | |||||
329 | ScDrawLayer::SetGlobalDrawPersist( aDragShellRef.get() ); | ||||
330 | std::unique_ptr<SdrModel> pModel(pDrawView->CreateMarkedObjModel()); | ||||
331 | ScDrawLayer::SetGlobalDrawPersist(nullptr); | ||||
332 | |||||
333 | ScViewData& rViewData = pView->GetViewData(); | ||||
334 | ScDocShell* pDocSh = rViewData.GetDocShell(); | ||||
335 | |||||
336 | TransferableObjectDescriptor aObjDesc; | ||||
337 | pDocSh->FillTransferableObjectDescriptor( aObjDesc ); | ||||
338 | aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); | ||||
339 | // maSize is set in ScDrawTransferObj ctor | ||||
340 | |||||
341 | rtl::Reference<ScDrawTransferObj> pTransferObj = new ScDrawTransferObj( std::move(pModel), pDocSh, aObjDesc ); | ||||
342 | |||||
343 | SfxObjectShellRef aPersistRef( aDragShellRef.get() ); | ||||
344 | pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive | ||||
345 | pTransferObj->SetDragSource( pDrawView ); // copies selection | ||||
346 | |||||
347 | mxDrawData = pTransferObj; | ||||
348 | } | ||||
349 | } | ||||
350 | OSL_ENSURE( mxDrawData.is(), "can't create DrawData" )do { if (true && (!(mxDrawData.is()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/app/seltrans.cxx" ":" "350" ": "), "%s", "can't create DrawData"); } } while ( false); | ||||
351 | } | ||||
352 | |||||
353 | ScTransferObj* ScSelectionTransferObj::GetCellData() | ||||
354 | { | ||||
355 | if ( !mxCellData.is() && ( eMode == SC_SELTRANS_CELL || eMode == SC_SELTRANS_CELLS ) ) | ||||
356 | CreateCellData(); | ||||
357 | return mxCellData.get(); | ||||
358 | } | ||||
359 | |||||
360 | ScDrawTransferObj* ScSelectionTransferObj::GetDrawData() | ||||
361 | { | ||||
362 | if ( !mxDrawData.is() && ( eMode
| ||||
363 | eMode == SC_SELTRANS_DRAW_BOOKMARK || eMode == SC_SELTRANS_DRAW_OLE || | ||||
364 | eMode == SC_SELTRANS_DRAW_OTHER ) ) | ||||
365 | CreateDrawData(); | ||||
366 | return mxDrawData.get(); | ||||
367 | } | ||||
368 | |||||
369 | bool ScSelectionTransferObj::GetData( | ||||
370 | const css::datatransfer::DataFlavor& rFlavor, const OUString& rDestDoc ) | ||||
371 | { | ||||
372 | bool bOK = false; | ||||
373 | |||||
374 | uno::Reference<datatransfer::XTransferable> xSource; | ||||
375 | switch (eMode) | ||||
| |||||
376 | { | ||||
377 | case SC_SELTRANS_CELL: | ||||
378 | case SC_SELTRANS_CELLS: | ||||
379 | xSource = GetCellData(); | ||||
380 | break; | ||||
381 | case SC_SELTRANS_DRAW_BITMAP: | ||||
382 | case SC_SELTRANS_DRAW_GRAPHIC: | ||||
383 | case SC_SELTRANS_DRAW_BOOKMARK: | ||||
384 | case SC_SELTRANS_DRAW_OLE: | ||||
385 | case SC_SELTRANS_DRAW_OTHER: | ||||
386 | xSource = GetDrawData(); | ||||
387 | break; | ||||
388 | default: | ||||
389 | { | ||||
390 | // added to avoid warnings | ||||
391 | } | ||||
392 | } | ||||
393 | |||||
394 | if ( xSource.is() ) | ||||
395 | { | ||||
396 | TransferableDataHelper aHelper( xSource ); | ||||
397 | uno::Any aAny = aHelper.GetAny(rFlavor, rDestDoc); | ||||
398 | bOK = SetAny( aAny ); | ||||
399 | } | ||||
400 | |||||
401 | return bOK; | ||||
402 | } | ||||
403 | |||||
404 | void ScSelectionTransferObj::ObjectReleased() | ||||
405 | { | ||||
406 | // called when another selection is set from outside | ||||
407 | |||||
408 | ForgetView(); | ||||
409 | |||||
410 | ScModule* pScMod = SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule ::Calc)) ); | ||||
411 | if ( pScMod->GetSelectionTransfer() == this ) | ||||
412 | pScMod->SetSelectionTransfer( nullptr ); | ||||
413 | |||||
414 | TransferableHelper::ObjectReleased(); | ||||
415 | } | ||||
416 | |||||
417 | sal_Bool SAL_CALL ScSelectionTransferObj::isComplex() | ||||
418 | { | ||||
419 | switch (eMode) | ||||
420 | { | ||||
421 | case SC_SELTRANS_CELL: | ||||
422 | case SC_SELTRANS_CELLS: | ||||
423 | return false; | ||||
424 | default: | ||||
425 | return true; | ||||
426 | } | ||||
427 | } | ||||
428 | |||||
429 | /* 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: */ |