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 <svx/svditer.hxx> | |||
21 | #include <svx/svdograf.hxx> | |||
22 | #include <svx/svdogrp.hxx> | |||
23 | #include <svx/svdoole2.hxx> | |||
24 | #include <svx/svdundo.hxx> | |||
25 | #include <sfx2/docfile.hxx> | |||
26 | #include <tools/urlobj.hxx> | |||
27 | #include <toolkit/helper/vclunohelper.hxx> | |||
28 | #include <sal/log.hxx> | |||
29 | ||||
30 | #include <drawview.hxx> | |||
31 | #include <global.hxx> | |||
32 | #include <drwlayer.hxx> | |||
33 | #include <viewdata.hxx> | |||
34 | #include <document.hxx> | |||
35 | #include <docsh.hxx> | |||
36 | #include <drwtrans.hxx> | |||
37 | #include <transobj.hxx> | |||
38 | #include <drawutil.hxx> | |||
39 | #include <scmod.hxx> | |||
40 | #include <globstr.hrc> | |||
41 | #include <scresid.hxx> | |||
42 | #include <gridwin.hxx> | |||
43 | #include <userdat.hxx> | |||
44 | ||||
45 | #include <com/sun/star/embed/NoVisualAreaSizeException.hpp> | |||
46 | #include <com/sun/star/embed/Aspects.hpp> | |||
47 | #include <com/sun/star/embed/XEmbeddedObject.hpp> | |||
48 | #include <com/sun/star/chart2/XChartTypeContainer.hpp> | |||
49 | #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> | |||
50 | #include <com/sun/star/chart2/XDataSeriesContainer.hpp> | |||
51 | #include <com/sun/star/chart2/XChartDocument.hpp> | |||
52 | ||||
53 | using namespace com::sun::star; | |||
54 | ||||
55 | Point aDragStartDiff; | |||
56 | ||||
57 | void ScDrawView::BeginDrag( vcl::Window* pWindow, const Point& rStartPos ) | |||
58 | { | |||
59 | if ( !AreObjectsMarked() ) | |||
| ||||
60 | return; | |||
61 | ||||
62 | BrkAction(); | |||
63 | ||||
64 | tools::Rectangle aMarkedRect = GetAllMarkedRect(); | |||
65 | ||||
66 | aDragStartDiff = rStartPos - aMarkedRect.TopLeft(); | |||
67 | ||||
68 | bool bAnyOle, bOneOle; | |||
69 | const SdrMarkList& rMarkList = GetMarkedObjectList(); | |||
70 | CheckOle( rMarkList, bAnyOle, bOneOle ); | |||
71 | ||||
72 | ScDocShellRef aDragShellRef; | |||
73 | if (bAnyOle) | |||
74 | { | |||
75 | aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately | |||
76 | aDragShellRef->DoInitNew(); | |||
77 | } | |||
78 | ScDrawLayer::SetGlobalDrawPersist( aDragShellRef.get() ); | |||
79 | std::unique_ptr<SdrModel> pModel(CreateMarkedObjModel()); | |||
80 | ScDrawLayer::SetGlobalDrawPersist(nullptr); | |||
81 | ||||
82 | // Charts now always copy their data in addition to the source reference, so | |||
83 | // there's no need to call SchDLL::Update for the charts in the clipboard doc. | |||
84 | // Update with the data (including NumberFormatter) from the live document would | |||
85 | // also store the NumberFormatter in the clipboard chart (#88749#) | |||
86 | ||||
87 | ScDocShell* pDocSh = pViewData->GetDocShell(); | |||
88 | ||||
89 | TransferableObjectDescriptor aObjDesc; | |||
90 | pDocSh->FillTransferableObjectDescriptor( aObjDesc ); | |||
91 | aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); | |||
92 | // maSize is set in ScDrawTransferObj ctor | |||
93 | ||||
94 | rtl::Reference<ScDrawTransferObj> pTransferObj = new ScDrawTransferObj( std::move(pModel), pDocSh, aObjDesc ); | |||
95 | ||||
96 | pTransferObj->SetDrawPersist( aDragShellRef.get() ); // keep persist for ole objects alive | |||
97 | pTransferObj->SetDragSource( this ); // copies selection | |||
98 | ||||
99 | SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule ::Calc)) )->SetDragObject( nullptr, pTransferObj.get() ); // for internal D&D | |||
100 | pTransferObj->StartDrag( pWindow, DND_ACTION_COPYMOVEcss::datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE | DND_ACTION_LINKcss::datatransfer::dnd::DNDConstants::ACTION_LINK ); | |||
101 | } | |||
102 | ||||
103 | namespace { | |||
104 | ||||
105 | void getRangeFromDataSource( uno::Reference< chart2::data::XDataSource > const & xDataSource, std::vector<OUString>& rRangeRep) | |||
106 | { | |||
107 | const uno::Sequence<uno::Reference<chart2::data::XLabeledDataSequence> > xSeqs = xDataSource->getDataSequences(); | |||
108 | for (const uno::Reference<chart2::data::XLabeledDataSequence>& xLS : xSeqs) | |||
109 | { | |||
110 | uno::Reference<chart2::data::XDataSequence> xSeq = xLS->getValues(); | |||
111 | if (xSeq.is()) | |||
112 | { | |||
113 | OUString aRep = xSeq->getSourceRangeRepresentation(); | |||
114 | rRangeRep.push_back(aRep); | |||
115 | } | |||
116 | xSeq = xLS->getLabel(); | |||
117 | if (xSeq.is()) | |||
118 | { | |||
119 | OUString aRep = xSeq->getSourceRangeRepresentation(); | |||
120 | rRangeRep.push_back(aRep); | |||
121 | } | |||
122 | } | |||
123 | } | |||
124 | ||||
125 | void getRangeFromErrorBar(const uno::Reference< chart2::XChartDocument >& rChartDoc, std::vector<OUString>& rRangeRep) | |||
126 | { | |||
127 | uno::Reference <chart2::XDiagram > xDiagram = rChartDoc->getFirstDiagram(); | |||
128 | if(!xDiagram.is()) | |||
129 | return; | |||
130 | ||||
131 | uno::Reference< chart2::XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY); | |||
132 | if(!xCooSysContainer.is()) | |||
133 | return; | |||
134 | ||||
135 | const uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > xCooSysSequence( xCooSysContainer->getCoordinateSystems()); | |||
136 | for(const auto& rCooSys : xCooSysSequence) | |||
137 | { | |||
138 | uno::Reference< chart2::XChartTypeContainer > xChartTypeContainer( rCooSys, uno::UNO_QUERY); | |||
139 | if(!xChartTypeContainer.is()) | |||
140 | continue; | |||
141 | ||||
142 | const uno::Sequence< uno::Reference< chart2::XChartType > > xChartTypeSequence( xChartTypeContainer->getChartTypes() ); | |||
143 | for(const auto& rChartType : xChartTypeSequence) | |||
144 | { | |||
145 | uno::Reference< chart2::XDataSeriesContainer > xDataSequenceContainer( rChartType, uno::UNO_QUERY); | |||
146 | if(!xDataSequenceContainer.is()) | |||
147 | continue; | |||
148 | ||||
149 | const uno::Sequence< uno::Reference< chart2::XDataSeries > > xSeriesSequence( xDataSequenceContainer->getDataSeries() ); | |||
150 | for(const uno::Reference<chart2::XDataSeries>& xSeries : xSeriesSequence) | |||
151 | { | |||
152 | uno::Reference< beans::XPropertySet > xPropSet( xSeries, uno::UNO_QUERY); | |||
153 | uno::Reference< chart2::data::XDataSource > xErrorBarY; | |||
154 | xPropSet->getPropertyValue("ErrorBarY") >>= xErrorBarY; | |||
155 | if(xErrorBarY.is()) | |||
156 | getRangeFromDataSource(xErrorBarY, rRangeRep); | |||
157 | uno::Reference< chart2::data::XDataSource > xErrorBarX; | |||
158 | xPropSet->getPropertyValue("ErrorBarX") >>= xErrorBarX; | |||
159 | if(xErrorBarX.is()) | |||
160 | getRangeFromDataSource(xErrorBarX, rRangeRep); | |||
161 | } | |||
162 | } | |||
163 | } | |||
164 | } | |||
165 | ||||
166 | void getRangeFromOle2Object(const SdrOle2Obj& rObj, std::vector<OUString>& rRangeRep) | |||
167 | { | |||
168 | if (!rObj.IsChart()) | |||
169 | // not a chart object. | |||
170 | return; | |||
171 | ||||
172 | const uno::Reference<embed::XEmbeddedObject>& xObj = rObj.GetObjRef(); | |||
173 | if (!xObj.is()) | |||
174 | return; | |||
175 | ||||
176 | uno::Reference<chart2::XChartDocument> xChartDoc(xObj->getComponent(), uno::UNO_QUERY); | |||
177 | if (!xChartDoc.is()) | |||
178 | return; | |||
179 | ||||
180 | if(xChartDoc->hasInternalDataProvider()) | |||
181 | return; | |||
182 | ||||
183 | getRangeFromErrorBar(xChartDoc, rRangeRep); | |||
184 | ||||
185 | uno::Reference<chart2::data::XDataSource> xDataSource(xChartDoc, uno::UNO_QUERY); | |||
186 | if (!xDataSource.is()) | |||
187 | return; | |||
188 | ||||
189 | // Get all data sources used in this chart. | |||
190 | getRangeFromDataSource(xDataSource, rRangeRep); | |||
191 | ||||
192 | return; | |||
193 | } | |||
194 | ||||
195 | // Get all cell ranges that are referenced by the selected chart objects. | |||
196 | void getOleSourceRanges(const SdrMarkList& rMarkList, bool& rAnyOle, bool& rOneOle, std::vector<ScRange>* pRanges = nullptr, const ScDocument* pDoc = nullptr ) | |||
197 | { | |||
198 | bool bCalcSourceRanges = pRanges && pDoc; | |||
199 | std::vector<OUString> aRangeReps; | |||
200 | rAnyOle = rOneOle = false; | |||
201 | const size_t nCount = rMarkList.GetMarkCount(); | |||
202 | for (size_t i=0; i<nCount; ++i) | |||
203 | { | |||
204 | SdrMark* pMark = rMarkList.GetMark(i); | |||
205 | if ( !pMark ) | |||
206 | continue; | |||
207 | ||||
208 | SdrObject* pObj = pMark->GetMarkedSdrObj(); | |||
209 | if ( !pObj ) | |||
210 | continue; | |||
211 | ||||
212 | sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier(); | |||
213 | if (nSdrObjKind == OBJ_OLE2) | |||
214 | { | |||
215 | rAnyOle = true; | |||
216 | rOneOle = (nCount == 1); | |||
217 | if ( bCalcSourceRanges ) | |||
218 | getRangeFromOle2Object( static_cast<const SdrOle2Obj&>( *pObj ), aRangeReps ); | |||
219 | else | |||
220 | break; | |||
221 | } | |||
222 | else if ( dynamic_cast<const SdrObjGroup*>( pObj) != nullptr ) | |||
223 | { | |||
224 | SdrObjListIter aIter( *pObj, SdrIterMode::DeepNoGroups ); | |||
225 | SdrObject* pSubObj = aIter.Next(); | |||
226 | while (pSubObj) | |||
227 | { | |||
228 | if ( pSubObj->GetObjIdentifier() == OBJ_OLE2 ) | |||
229 | { | |||
230 | rAnyOle = true; | |||
231 | // rOneOle remains false - a group isn't treated like a single OLE object | |||
232 | if ( !bCalcSourceRanges ) | |||
233 | return; | |||
234 | ||||
235 | getRangeFromOle2Object( static_cast<const SdrOle2Obj&>( *pSubObj ), aRangeReps ); | |||
236 | } | |||
237 | pSubObj = aIter.Next(); | |||
238 | } | |||
239 | } | |||
240 | } | |||
241 | ||||
242 | if (!bCalcSourceRanges) | |||
243 | return; | |||
244 | ||||
245 | // Compile all range representation strings into ranges. | |||
246 | for (const auto& rRangeRep : aRangeReps) | |||
247 | { | |||
248 | ScRangeList aRange; | |||
249 | ScAddress aAddr; | |||
250 | if (aRange.Parse(rRangeRep, *pDoc, pDoc->GetAddressConvention()) & ScRefFlags::VALID) | |||
251 | { | |||
252 | for(size_t i = 0; i < aRange.size(); ++i) | |||
253 | pRanges->push_back(aRange[i]); | |||
254 | } | |||
255 | else if (aAddr.Parse(rRangeRep, *pDoc, pDoc->GetAddressConvention()) & ScRefFlags::VALID) | |||
256 | pRanges->push_back(aAddr); | |||
257 | } | |||
258 | ||||
259 | return; | |||
260 | } | |||
261 | ||||
262 | class InsertTabIndex | |||
263 | { | |||
264 | std::vector<SCTAB>& mrTabs; | |||
265 | public: | |||
266 | explicit InsertTabIndex(std::vector<SCTAB>& rTabs) : mrTabs(rTabs) {} | |||
267 | void operator() (const ScRange& rRange) | |||
268 | { | |||
269 | mrTabs.push_back(rRange.aStart.Tab()); | |||
270 | } | |||
271 | }; | |||
272 | ||||
273 | class CopyRangeData | |||
274 | { | |||
275 | ScDocument& mrSrc; | |||
276 | ScDocument& mrDest; | |||
277 | public: | |||
278 | CopyRangeData(ScDocument& rSrc, ScDocument& rDest) : mrSrc(rSrc), mrDest(rDest) {} | |||
279 | ||||
280 | void operator() (const ScRange& rRange) | |||
281 | { | |||
282 | OUString aTabName; | |||
283 | mrSrc.GetName(rRange.aStart.Tab(), aTabName); | |||
284 | ||||
285 | SCTAB nTab; | |||
286 | if (!mrDest.GetTable(aTabName, nTab)) | |||
287 | // Sheet by this name doesn't exist. | |||
288 | return; | |||
289 | ||||
290 | mrSrc.CopyStaticToDocument(rRange, nTab, mrDest); | |||
291 | } | |||
292 | }; | |||
293 | ||||
294 | void copyChartRefDataToClipDoc(ScDocument& rSrcDoc, ScDocument& rClipDoc, const std::vector<ScRange>& rRanges) | |||
295 | { | |||
296 | // Get a list of referenced table indices. | |||
297 | std::vector<SCTAB> aTabs; | |||
298 | std::for_each(rRanges.begin(), rRanges.end(), InsertTabIndex(aTabs)); | |||
299 | std::sort(aTabs.begin(), aTabs.end()); | |||
300 | aTabs.erase(std::unique(aTabs.begin(), aTabs.end()), aTabs.end()); | |||
301 | ||||
302 | // Get table names. | |||
303 | if (aTabs.empty()) | |||
304 | return; | |||
305 | ||||
306 | // Create sheets only for referenced source sheets. | |||
307 | OUString aName; | |||
308 | std::vector<SCTAB>::const_iterator it = aTabs.begin(), itEnd = aTabs.end(); | |||
309 | if (!rSrcDoc.GetName(*it, aName)) | |||
310 | return; | |||
311 | ||||
312 | rClipDoc.SetTabNameOnLoad(0, aName); // document initially has one sheet. | |||
313 | ||||
314 | for (++it; it != itEnd; ++it) | |||
315 | { | |||
316 | if (!rSrcDoc.GetName(*it, aName)) | |||
317 | return; | |||
318 | ||||
319 | rClipDoc.AppendTabOnLoad(aName); | |||
320 | } | |||
321 | ||||
322 | std::for_each(rRanges.begin(), rRanges.end(), CopyRangeData(rSrcDoc, rClipDoc)); | |||
323 | } | |||
324 | ||||
325 | } | |||
326 | ||||
327 | void ScDrawView::CheckOle( const SdrMarkList& rMarkList, bool& rAnyOle, bool& rOneOle ) | |||
328 | { | |||
329 | getOleSourceRanges( rMarkList, rAnyOle, rOneOle ); | |||
330 | } | |||
331 | ||||
332 | void ScDrawView::DoCopy() | |||
333 | { | |||
334 | const SdrMarkList& rMarkList = GetMarkedObjectList(); | |||
335 | std::vector<ScRange> aRanges; | |||
336 | bool bAnyOle = false, bOneOle = false; | |||
337 | getOleSourceRanges( rMarkList, bAnyOle, bOneOle, &aRanges, &rDoc ); | |||
338 | ||||
339 | // update ScGlobal::xDrawClipDocShellRef | |||
340 | ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) ); | |||
341 | if (ScGlobal::xDrawClipDocShellRef.is() && !aRanges.empty()) | |||
342 | { | |||
343 | // Copy data referenced by the chart objects to the draw clip | |||
344 | // document. We need to do this before CreateMarkedObjModel() below. | |||
345 | ScDocShellRef xDocSh = ScGlobal::xDrawClipDocShellRef; | |||
346 | ScDocument& rClipDoc = xDocSh->GetDocument(); | |||
347 | copyChartRefDataToClipDoc(rDoc, rClipDoc, aRanges); | |||
348 | } | |||
349 | std::unique_ptr<SdrModel> pModel(CreateMarkedObjModel()); | |||
350 | ScDrawLayer::SetGlobalDrawPersist(nullptr); | |||
351 | ||||
352 | // Charts now always copy their data in addition to the source reference, so | |||
353 | // there's no need to call SchDLL::Update for the charts in the clipboard doc. | |||
354 | // Update with the data (including NumberFormatter) from the live document would | |||
355 | // also store the NumberFormatter in the clipboard chart (#88749#) | |||
356 | ||||
357 | ScDocShell* pDocSh = pViewData->GetDocShell(); | |||
358 | ||||
359 | TransferableObjectDescriptor aObjDesc; | |||
360 | pDocSh->FillTransferableObjectDescriptor( aObjDesc ); | |||
361 | aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); | |||
362 | // maSize is set in ScDrawTransferObj ctor | |||
363 | ||||
364 | rtl::Reference<ScDrawTransferObj> pTransferObj(new ScDrawTransferObj( std::move(pModel), pDocSh, aObjDesc )); | |||
365 | ||||
366 | if ( ScGlobal::xDrawClipDocShellRef.is() ) | |||
367 | { | |||
368 | pTransferObj->SetDrawPersist( ScGlobal::xDrawClipDocShellRef.get() ); // keep persist for ole objects alive | |||
369 | } | |||
370 | ||||
371 | pTransferObj->CopyToClipboard( pViewData->GetActiveWin() ); // system clipboard | |||
372 | } | |||
373 | ||||
374 | uno::Reference<datatransfer::XTransferable> ScDrawView::CopyToTransferable() | |||
375 | { | |||
376 | bool bAnyOle, bOneOle; | |||
377 | const SdrMarkList& rMarkList = GetMarkedObjectList(); | |||
378 | CheckOle( rMarkList, bAnyOle, bOneOle ); | |||
379 | ||||
380 | // update ScGlobal::xDrawClipDocShellRef | |||
381 | ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) ); | |||
382 | std::unique_ptr<SdrModel> pModel( CreateMarkedObjModel() ); | |||
383 | ScDrawLayer::SetGlobalDrawPersist(nullptr); | |||
384 | ||||
385 | // Charts now always copy their data in addition to the source reference, so | |||
386 | // there's no need to call SchDLL::Update for the charts in the clipboard doc. | |||
387 | // Update with the data (including NumberFormatter) from the live document would | |||
388 | // also store the NumberFormatter in the clipboard chart (#88749#) | |||
389 | // lcl_RefreshChartData( pModel, pViewData->GetDocument() ); | |||
390 | ||||
391 | ScDocShell* pDocSh = pViewData->GetDocShell(); | |||
392 | ||||
393 | TransferableObjectDescriptor aObjDesc; | |||
394 | pDocSh->FillTransferableObjectDescriptor( aObjDesc ); | |||
395 | aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); | |||
396 | // maSize is set in ScDrawTransferObj ctor | |||
397 | ||||
398 | ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( std::move(pModel), pDocSh, aObjDesc ); | |||
399 | uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj ); | |||
400 | ||||
401 | if ( ScGlobal::xDrawClipDocShellRef.is() ) | |||
402 | { | |||
403 | pTransferObj->SetDrawPersist( ScGlobal::xDrawClipDocShellRef.get() ); // keep persist for ole objects alive | |||
404 | } | |||
405 | ||||
406 | return xTransferable; | |||
407 | } | |||
408 | ||||
409 | // Calculate correction for 100%, regardless of current settings | |||
410 | ||||
411 | void ScDrawView::CalcNormScale( Fraction& rFractX, Fraction& rFractY ) const | |||
412 | { | |||
413 | double nPPTX = ScGlobal::nScreenPPTX; | |||
414 | double nPPTY = ScGlobal::nScreenPPTY; | |||
415 | ||||
416 | if (pViewData) | |||
417 | nPPTX /= pViewData->GetDocShell()->GetOutputFactor(); | |||
418 | ||||
419 | SCCOL nEndCol = 0; | |||
420 | SCROW nEndRow = 0; | |||
421 | rDoc.GetTableArea( nTab, nEndCol, nEndRow ); | |||
422 | if (nEndCol<20) | |||
423 | nEndCol = 20; | |||
424 | if (nEndRow<20) | |||
425 | nEndRow = 1000; | |||
426 | ||||
427 | Fraction aZoom(1,1); | |||
428 | ScDrawUtil::CalcScale( rDoc, nTab, 0,0, nEndCol,nEndRow, pDev, aZoom,aZoom, | |||
429 | nPPTX, nPPTY, rFractX,rFractY ); | |||
430 | } | |||
431 | ||||
432 | void ScDrawView::SetMarkedOriginalSize() | |||
433 | { | |||
434 | std::unique_ptr<SdrUndoGroup> pUndoGroup(new SdrUndoGroup(*GetModel())); | |||
435 | ||||
436 | const SdrMarkList& rMarkList = GetMarkedObjectList(); | |||
437 | long nDone = 0; | |||
438 | const size_t nCount = rMarkList.GetMarkCount(); | |||
439 | for (size_t i=0; i<nCount; ++i) | |||
440 | { | |||
441 | SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj(); | |||
442 | sal_uInt16 nIdent = pObj->GetObjIdentifier(); | |||
443 | bool bDo = false; | |||
444 | Size aOriginalSize; | |||
445 | if (nIdent == OBJ_OLE2) | |||
446 | { | |||
447 | // TODO/LEAN: working with visual area can switch object to running state | |||
448 | uno::Reference < embed::XEmbeddedObject > xObj = static_cast<SdrOle2Obj*>(pObj)->GetObjRef(); | |||
449 | if ( xObj.is() ) // NULL for an invalid object that couldn't be loaded | |||
450 | { | |||
451 | sal_Int64 nAspect = static_cast<SdrOle2Obj*>(pObj)->GetAspect(); | |||
452 | ||||
453 | if ( nAspect == embed::Aspects::MSOLE_ICON ) | |||
454 | { | |||
455 | MapMode aMapMode( MapUnit::Map100thMM ); | |||
456 | aOriginalSize = static_cast<SdrOle2Obj*>(pObj)->GetOrigObjSize( &aMapMode ); | |||
457 | bDo = true; | |||
458 | } | |||
459 | else | |||
460 | { | |||
461 | MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( static_cast<SdrOle2Obj*>(pObj)->GetAspect() ) ); | |||
462 | try | |||
463 | { | |||
464 | awt::Size aSz = xObj->getVisualAreaSize( static_cast<SdrOle2Obj*>(pObj)->GetAspect() ); | |||
465 | aOriginalSize = OutputDevice::LogicToLogic( | |||
466 | Size( aSz.Width, aSz.Height ), | |||
467 | MapMode(aUnit), | |||
468 | MapMode(MapUnit::Map100thMM)); | |||
469 | bDo = true; | |||
470 | } catch( embed::NoVisualAreaSizeException& ) | |||
471 | { | |||
472 | OSL_ENSURE( false, "Can't get the original size of the object!" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawvie4.cxx" ":" "472" ": "), "%s", "Can't get the original size of the object!" ); } } while (false); | |||
473 | } | |||
474 | } | |||
475 | } | |||
476 | } | |||
477 | else if (nIdent == OBJ_GRAF) | |||
478 | { | |||
479 | const Graphic& rGraphic = static_cast<SdrGrafObj*>(pObj)->GetGraphic(); | |||
480 | ||||
481 | MapMode aSourceMap = rGraphic.GetPrefMapMode(); | |||
482 | MapMode aDestMap( MapUnit::Map100thMM ); | |||
483 | if (aSourceMap.GetMapUnit() == MapUnit::MapPixel) | |||
484 | { | |||
485 | // consider pixel correction, so that the bitmap is correct on the screen | |||
486 | Fraction aNormScaleX, aNormScaleY; | |||
487 | CalcNormScale( aNormScaleX, aNormScaleY ); | |||
488 | aDestMap.SetScaleX(aNormScaleX); | |||
489 | aDestMap.SetScaleY(aNormScaleY); | |||
490 | } | |||
491 | if (pViewData) | |||
492 | { | |||
493 | vcl::Window* pActWin = pViewData->GetActiveWin(); | |||
494 | if (pActWin) | |||
495 | { | |||
496 | aOriginalSize = pActWin->LogicToLogic( | |||
497 | rGraphic.GetPrefSize(), &aSourceMap, &aDestMap ); | |||
498 | bDo = true; | |||
499 | } | |||
500 | } | |||
501 | } | |||
502 | ||||
503 | if ( bDo ) | |||
504 | { | |||
505 | tools::Rectangle aDrawRect = pObj->GetLogicRect(); | |||
506 | ||||
507 | pUndoGroup->AddAction( std::make_unique<SdrUndoGeoObj>( *pObj ) ); | |||
508 | pObj->Resize( aDrawRect.TopLeft(), Fraction( aOriginalSize.Width(), aDrawRect.GetWidth() ), | |||
509 | Fraction( aOriginalSize.Height(), aDrawRect.GetHeight() ) ); | |||
510 | ++nDone; | |||
511 | } | |||
512 | } | |||
513 | ||||
514 | if (nDone && pViewData) | |||
515 | { | |||
516 | pUndoGroup->SetComment(ScResId( STR_UNDO_ORIGINALSIZEreinterpret_cast<char const *>("STR_UNDO_ORIGINALSIZE" "\004" u8"Original Size") )); | |||
517 | ScDocShell* pDocSh = pViewData->GetDocShell(); | |||
518 | pDocSh->GetUndoManager()->AddUndoAction(std::move(pUndoGroup)); | |||
519 | pDocSh->SetDrawModified(); | |||
520 | } | |||
521 | } | |||
522 | ||||
523 | void ScDrawView::FitToCellSize() | |||
524 | { | |||
525 | const SdrMarkList& rMarkList = GetMarkedObjectList(); | |||
526 | ||||
527 | if (rMarkList.GetMarkCount() != 1) | |||
528 | { | |||
529 | SAL_WARN("sc.ui", "Fit to cell only works with one graphic!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sc.ui")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Fit to cell only works with one graphic!") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc.ui") , ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawvie4.cxx" ":" "529" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Fit to cell only works with one graphic!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Fit to cell only works with one graphic!"; ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc.ui"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawvie4.cxx" ":" "529" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Fit to cell only works with one graphic!") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc.ui") , ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawvie4.cxx" ":" "529" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Fit to cell only works with one graphic!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Fit to cell only works with one graphic!"; ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc.ui"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawvie4.cxx" ":" "529" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
530 | return; | |||
531 | } | |||
532 | ||||
533 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); | |||
534 | ||||
535 | ScAnchorType aAnchorType = ScDrawLayer::GetAnchorType(*pObj); | |||
536 | if (aAnchorType != SCA_CELL && aAnchorType != SCA_CELL_RESIZE) | |||
537 | { | |||
538 | SAL_WARN("sc.ui", "Fit to cell only works with cell anchored graphics!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sc.ui")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Fit to cell only works with cell anchored graphics!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc.ui" ), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawvie4.cxx" ":" "538" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Fit to cell only works with cell anchored graphics!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Fit to cell only works with cell anchored graphics!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc.ui" ), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawvie4.cxx" ":" "538" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Fit to cell only works with cell anchored graphics!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc.ui" ), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawvie4.cxx" ":" "538" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Fit to cell only works with cell anchored graphics!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Fit to cell only works with cell anchored graphics!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc.ui" ), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawvie4.cxx" ":" "538" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
539 | return; | |||
540 | } | |||
541 | ||||
542 | ScDrawObjData* pObjData = ScDrawLayer::GetObjData(pObj); | |||
543 | if (!pObjData) | |||
544 | { | |||
545 | SAL_WARN("sc.ui", "Missing ScDrawObjData!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sc.ui")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Missing ScDrawObjData!") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc.ui"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawvie4.cxx" ":" "545" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Missing ScDrawObjData!"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Missing ScDrawObjData!"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sc.ui"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawvie4.cxx" ":" "545" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Missing ScDrawObjData!") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc.ui"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawvie4.cxx" ":" "545" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Missing ScDrawObjData!"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Missing ScDrawObjData!"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sc.ui"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawvie4.cxx" ":" "545" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
546 | return; | |||
547 | } | |||
548 | ||||
549 | std::unique_ptr<SdrUndoGroup> pUndoGroup(new SdrUndoGroup(*GetModel())); | |||
550 | tools::Rectangle aGraphicRect = pObj->GetSnapRect(); | |||
551 | tools::Rectangle aCellRect = ScDrawLayer::GetCellRect( rDoc, pObjData->maStart, true); | |||
552 | ||||
553 | // For graphic objects, we want to keep the aspect ratio | |||
554 | if (pObj->shouldKeepAspectRatio()) | |||
555 | { | |||
556 | long nWidth = aGraphicRect.GetWidth(); | |||
557 | assert(nWidth && "div-by-zero")(static_cast <bool> (nWidth && "div-by-zero") ? void (0) : __assert_fail ("nWidth && \"div-by-zero\"" , "/home/maarten/src/libreoffice/core/sc/source/ui/view/drawvie4.cxx" , 557, __extension__ __PRETTY_FUNCTION__)); | |||
558 | double fScaleX = static_cast<double>(aCellRect.GetWidth()) / static_cast<double>(nWidth); | |||
559 | long nHeight = aGraphicRect.GetHeight(); | |||
560 | assert(nHeight && "div-by-zero")(static_cast <bool> (nHeight && "div-by-zero") ? void (0) : __assert_fail ("nHeight && \"div-by-zero\"" , "/home/maarten/src/libreoffice/core/sc/source/ui/view/drawvie4.cxx" , 560, __extension__ __PRETTY_FUNCTION__)); | |||
561 | double fScaleY = static_cast<double>(aCellRect.GetHeight()) / static_cast<double>(nHeight); | |||
562 | double fScaleMin = std::min(fScaleX, fScaleY); | |||
563 | ||||
564 | aCellRect.setWidth(static_cast<double>(aGraphicRect.GetWidth()) * fScaleMin); | |||
565 | aCellRect.setHeight(static_cast<double>(aGraphicRect.GetHeight()) * fScaleMin); | |||
566 | } | |||
567 | ||||
568 | pUndoGroup->AddAction( std::make_unique<SdrUndoGeoObj>( *pObj ) ); | |||
569 | if (pObj->GetObjIdentifier() == OBJ_CUSTOMSHAPE) | |||
570 | pObj->AdjustToMaxRect(aCellRect); | |||
571 | else | |||
572 | pObj->SetSnapRect(aCellRect); | |||
573 | ||||
574 | pUndoGroup->SetComment(ScResId( STR_UNDO_FITCELLSIZEreinterpret_cast<char const *>("STR_UNDO_FITCELLSIZE" "\004" u8"Fit to Cell Size") )); | |||
575 | ScDocShell* pDocSh = pViewData->GetDocShell(); | |||
576 | pDocSh->GetUndoManager()->AddUndoAction(std::move(pUndoGroup)); | |||
577 | ||||
578 | } | |||
579 | ||||
580 | /* 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: */ |