File: | home/maarten/src/libreoffice/core/sc/source/ui/unoobj/chartuno.cxx |
Warning: | line 693, column 9 2nd function call argument is an uninitialized value |
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/embed/Aspects.hpp> | ||||||||
21 | #include <com/sun/star/embed/XEmbeddedObject.hpp> | ||||||||
22 | #include <com/sun/star/awt/Size.hpp> | ||||||||
23 | #include <com/sun/star/beans/PropertyAttribute.hpp> | ||||||||
24 | #include <com/sun/star/chart2/data/XDataReceiver.hpp> | ||||||||
25 | #include <com/sun/star/chart/ChartDataRowSource.hpp> | ||||||||
26 | #include <com/sun/star/chart2/XChartDocument.hpp> | ||||||||
27 | #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> | ||||||||
28 | #include <com/sun/star/table/CellRangeAddress.hpp> | ||||||||
29 | |||||||||
30 | #include <osl/diagnose.h> | ||||||||
31 | #include <svx/svditer.hxx> | ||||||||
32 | #include <svx/svdoole2.hxx> | ||||||||
33 | #include <svx/svdpage.hxx> | ||||||||
34 | #include <svx/svdundo.hxx> | ||||||||
35 | #include <unotools/moduleoptions.hxx> | ||||||||
36 | #include <comphelper/classids.hxx> | ||||||||
37 | #include <toolkit/helper/vclunohelper.hxx> | ||||||||
38 | #include <tools/globname.hxx> | ||||||||
39 | #include <svtools/embedhlp.hxx> | ||||||||
40 | #include <vcl/svapp.hxx> | ||||||||
41 | |||||||||
42 | #include <ChartTools.hxx> | ||||||||
43 | #include <chartuno.hxx> | ||||||||
44 | #include <miscuno.hxx> | ||||||||
45 | #include <docsh.hxx> | ||||||||
46 | #include <drwlayer.hxx> | ||||||||
47 | #include <undodat.hxx> | ||||||||
48 | #include <chartlis.hxx> | ||||||||
49 | #include <chart2uno.hxx> | ||||||||
50 | #include <convuno.hxx> | ||||||||
51 | |||||||||
52 | using namespace css; | ||||||||
53 | |||||||||
54 | #define PROP_HANDLE_RELATED_CELLRANGES1 1 | ||||||||
55 | |||||||||
56 | SC_SIMPLE_SERVICE_INFO( ScChartObj, "ScChartObj", "com.sun.star.table.TableChart" )OUString ScChartObj::getImplementationName() { return "ScChartObj" ; } sal_Bool ScChartObj::supportsService( const OUString& ServiceName ) { return cppu::supportsService(this, ServiceName ); } css::uno::Sequence< OUString > ScChartObj::getSupportedServiceNames () { css::uno::Sequence< OUString > aRet { "com.sun.star.table.TableChart" }; return aRet; } | ||||||||
57 | SC_SIMPLE_SERVICE_INFO( ScChartsObj, "ScChartsObj", "com.sun.star.table.TableCharts" )OUString ScChartsObj::getImplementationName() { return "ScChartsObj" ; } sal_Bool ScChartsObj::supportsService( const OUString& ServiceName ) { return cppu::supportsService(this, ServiceName ); } css::uno::Sequence< OUString > ScChartsObj::getSupportedServiceNames () { css::uno::Sequence< OUString > aRet { "com.sun.star.table.TableCharts" }; return aRet; } | ||||||||
58 | |||||||||
59 | ScChartsObj::ScChartsObj(ScDocShell* pDocSh, SCTAB nT) : | ||||||||
60 | pDocShell( pDocSh ), | ||||||||
61 | nTab( nT ) | ||||||||
62 | { | ||||||||
63 | pDocShell->GetDocument().AddUnoObject(*this); | ||||||||
64 | } | ||||||||
65 | |||||||||
66 | ScChartsObj::~ScChartsObj() | ||||||||
67 | { | ||||||||
68 | SolarMutexGuard g; | ||||||||
69 | |||||||||
70 | if (pDocShell) | ||||||||
71 | pDocShell->GetDocument().RemoveUnoObject(*this); | ||||||||
72 | } | ||||||||
73 | |||||||||
74 | void ScChartsObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) | ||||||||
75 | { | ||||||||
76 | //! update reference | ||||||||
77 | |||||||||
78 | if ( rHint.GetId() == SfxHintId::Dying ) | ||||||||
79 | { | ||||||||
80 | pDocShell = nullptr; | ||||||||
81 | } | ||||||||
82 | } | ||||||||
83 | |||||||||
84 | ScChartObj* ScChartsObj::GetObjectByIndex_Impl(long nIndex) const | ||||||||
85 | { | ||||||||
86 | OUString aName; | ||||||||
87 | if ( pDocShell ) | ||||||||
88 | { | ||||||||
89 | ScDocument& rDoc = pDocShell->GetDocument(); | ||||||||
90 | ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer(); | ||||||||
91 | if (pDrawLayer) | ||||||||
92 | { | ||||||||
93 | SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); | ||||||||
94 | OSL_ENSURE(pPage, "Page not found")do { if (true && (!(pPage))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/unoobj/chartuno.cxx" ":" "94" ": "), "%s", "Page not found"); } } while (false); | ||||||||
95 | if (pPage) | ||||||||
96 | { | ||||||||
97 | long nPos = 0; | ||||||||
98 | SdrObjListIter aIter( pPage, SdrIterMode::DeepNoGroups ); | ||||||||
99 | SdrObject* pObject = aIter.Next(); | ||||||||
100 | while (pObject) | ||||||||
101 | { | ||||||||
102 | if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ScDocument::IsChart(pObject) ) | ||||||||
103 | { | ||||||||
104 | if ( nPos == nIndex ) | ||||||||
105 | { | ||||||||
106 | uno::Reference < embed::XEmbeddedObject > xObj = static_cast<SdrOle2Obj*>(pObject)->GetObjRef(); | ||||||||
107 | if ( xObj.is() ) | ||||||||
108 | aName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj ); | ||||||||
109 | break; // stop searching | ||||||||
110 | } | ||||||||
111 | ++nPos; | ||||||||
112 | } | ||||||||
113 | pObject = aIter.Next(); | ||||||||
114 | } | ||||||||
115 | } | ||||||||
116 | } | ||||||||
117 | } | ||||||||
118 | |||||||||
119 | if (!aName.isEmpty()) | ||||||||
120 | return new ScChartObj( pDocShell, nTab, aName ); | ||||||||
121 | return nullptr; | ||||||||
122 | } | ||||||||
123 | |||||||||
124 | ScChartObj* ScChartsObj::GetObjectByName_Impl(const OUString& aName) const | ||||||||
125 | { | ||||||||
126 | if (sc::tools::findChartsByName(pDocShell, nTab, aName, sc::tools::ChartSourceType::CELL_RANGE)) | ||||||||
127 | return new ScChartObj( pDocShell, nTab, aName ); | ||||||||
128 | return nullptr; | ||||||||
129 | } | ||||||||
130 | |||||||||
131 | // XTableCharts | ||||||||
132 | |||||||||
133 | void SAL_CALL ScChartsObj::addNewByName( const OUString& rName, | ||||||||
134 | const awt::Rectangle& aRect, | ||||||||
135 | const uno::Sequence<table::CellRangeAddress>& aRanges, | ||||||||
136 | sal_Bool bColumnHeaders, sal_Bool bRowHeaders ) | ||||||||
137 | { | ||||||||
138 | SolarMutexGuard aGuard; | ||||||||
139 | if (!pDocShell) | ||||||||
140 | return; | ||||||||
141 | |||||||||
142 | ScDocument& rDoc = pDocShell->GetDocument(); | ||||||||
143 | ScDrawLayer* pModel = pDocShell->MakeDrawLayer(); | ||||||||
144 | SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab)); | ||||||||
145 | OSL_ENSURE(pPage,"addChart: no Page")do { if (true && (!(pPage))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/unoobj/chartuno.cxx" ":" "145" ": "), "%s", "addChart: no Page"); } } while (false ); | ||||||||
146 | if (!pPage) | ||||||||
147 | return; | ||||||||
148 | |||||||||
149 | // chart can't be inserted if any ole object with that name exists on any table | ||||||||
150 | // (empty string: generate valid name) | ||||||||
151 | |||||||||
152 | OUString aName = rName; | ||||||||
153 | SCTAB nDummy; | ||||||||
154 | if ( !aName.isEmpty() && pModel->GetNamedObject( aName, OBJ_OLE2, nDummy ) ) | ||||||||
155 | { | ||||||||
156 | // object exists - only RuntimeException is specified | ||||||||
157 | throw uno::RuntimeException(); | ||||||||
158 | } | ||||||||
159 | |||||||||
160 | ScRangeList* pList = new ScRangeList; | ||||||||
161 | for (const table::CellRangeAddress& rRange : aRanges) | ||||||||
162 | { | ||||||||
163 | ScRange aRange( static_cast<SCCOL>(rRange.StartColumn), rRange.StartRow, rRange.Sheet, | ||||||||
164 | static_cast<SCCOL>(rRange.EndColumn), rRange.EndRow, rRange.Sheet ); | ||||||||
165 | pList->push_back( aRange ); | ||||||||
166 | } | ||||||||
167 | ScRangeListRef xNewRanges( pList ); | ||||||||
168 | |||||||||
169 | uno::Reference < embed::XEmbeddedObject > xObj; | ||||||||
170 | if ( SvtModuleOptions().IsChart() ) | ||||||||
171 | xObj = pDocShell->GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID0x12DCAE26, 0x281F, 0x416F, 0xA2, 0x34, 0xC3, 0x08, 0x61, 0x27 , 0x38, 0x2E ).GetByteSequence(), aName ); | ||||||||
172 | if ( !xObj.is() ) | ||||||||
173 | return; | ||||||||
174 | |||||||||
175 | // adjust rectangle | ||||||||
176 | //! error/exception, if empty/invalid ??? | ||||||||
177 | Point aRectPos( aRect.X, aRect.Y ); | ||||||||
178 | bool bLayoutRTL = rDoc.IsLayoutRTL( nTab ); | ||||||||
179 | if ( ( aRectPos.X() < 0 && !bLayoutRTL ) || ( aRectPos.X() > 0 && bLayoutRTL ) ) | ||||||||
180 | aRectPos.setX( 0 ); | ||||||||
181 | |||||||||
182 | if (aRectPos.Y() < 0) | ||||||||
183 | aRectPos.setY( 0 ); | ||||||||
184 | |||||||||
185 | Size aRectSize( aRect.Width, aRect.Height ); | ||||||||
186 | if (aRectSize.Width() <= 0) | ||||||||
187 | aRectSize.setWidth( 5000 ); // default size | ||||||||
188 | |||||||||
189 | if (aRectSize.Height() <= 0) | ||||||||
190 | aRectSize.setHeight( 5000 ); | ||||||||
191 | tools::Rectangle aInsRect( aRectPos, aRectSize ); | ||||||||
192 | |||||||||
193 | sal_Int64 nAspect(embed::Aspects::MSOLE_CONTENT); | ||||||||
194 | MapUnit aMapUnit(VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) )); | ||||||||
195 | Size aSize(aInsRect.GetSize()); | ||||||||
196 | aSize = OutputDevice::LogicToLogic( aSize, MapMode( MapUnit::Map100thMM ), MapMode( aMapUnit ) ); | ||||||||
197 | awt::Size aSz; | ||||||||
198 | aSz.Width = aSize.Width(); | ||||||||
199 | aSz.Height = aSize.Height(); | ||||||||
200 | |||||||||
201 | // Calc -> DataProvider | ||||||||
202 | uno::Reference< chart2::data::XDataProvider > xDataProvider = new | ||||||||
203 | ScChart2DataProvider( &rDoc ); | ||||||||
204 | // Chart -> DataReceiver | ||||||||
205 | uno::Reference< chart2::data::XDataReceiver > xReceiver; | ||||||||
206 | if( xObj.is()) | ||||||||
207 | xReceiver.set( xObj->getComponent(), uno::UNO_QUERY ); | ||||||||
208 | if( xReceiver.is()) | ||||||||
209 | { | ||||||||
210 | OUString sRangeStr; | ||||||||
211 | xNewRanges->Format(sRangeStr, ScRefFlags::RANGE_ABS_3D, rDoc); | ||||||||
212 | |||||||||
213 | // connect | ||||||||
214 | if( !sRangeStr.isEmpty() ) | ||||||||
215 | xReceiver->attachDataProvider( xDataProvider ); | ||||||||
216 | else | ||||||||
217 | sRangeStr = "all"; | ||||||||
218 | |||||||||
219 | uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( pDocShell->GetModel(), uno::UNO_QUERY ); | ||||||||
220 | xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier ); | ||||||||
221 | |||||||||
222 | // set arguments | ||||||||
223 | uno::Sequence< beans::PropertyValue > aArgs( 4 ); | ||||||||
224 | aArgs[0] = beans::PropertyValue( | ||||||||
225 | "CellRangeRepresentation", -1, | ||||||||
226 | uno::makeAny( sRangeStr ), beans::PropertyState_DIRECT_VALUE ); | ||||||||
227 | aArgs[1] = beans::PropertyValue( | ||||||||
228 | "HasCategories", -1, | ||||||||
229 | uno::makeAny( bRowHeaders ), beans::PropertyState_DIRECT_VALUE ); | ||||||||
230 | aArgs[2] = beans::PropertyValue( | ||||||||
231 | "FirstCellAsLabel", -1, | ||||||||
232 | uno::makeAny( bColumnHeaders ), beans::PropertyState_DIRECT_VALUE ); | ||||||||
233 | aArgs[3] = beans::PropertyValue( | ||||||||
234 | "DataRowSource", -1, | ||||||||
235 | uno::makeAny( chart::ChartDataRowSource_COLUMNS ), beans::PropertyState_DIRECT_VALUE ); | ||||||||
236 | xReceiver->setArguments( aArgs ); | ||||||||
237 | } | ||||||||
238 | |||||||||
239 | ScChartListener* pChartListener = | ||||||||
240 | new ScChartListener( aName, rDoc, xNewRanges ); | ||||||||
241 | rDoc.GetChartListenerCollection()->insert( pChartListener ); | ||||||||
242 | pChartListener->StartListeningTo(); | ||||||||
243 | |||||||||
244 | SdrOle2Obj* pObj = new SdrOle2Obj( | ||||||||
245 | *pModel, | ||||||||
246 | ::svt::EmbeddedObjectRef(xObj, embed::Aspects::MSOLE_CONTENT), | ||||||||
247 | aName, | ||||||||
248 | aInsRect); | ||||||||
249 | |||||||||
250 | // set VisArea | ||||||||
251 | if( xObj.is()) | ||||||||
252 | xObj->setVisualAreaSize( nAspect, aSz ); | ||||||||
253 | |||||||||
254 | // #i121334# This call will change the chart's default background fill from white to transparent. | ||||||||
255 | // Add here again if this is wanted (see task description for details) | ||||||||
256 | // ChartHelper::AdaptDefaultsForChart( xObj ); | ||||||||
257 | |||||||||
258 | pPage->InsertObject( pObj ); | ||||||||
259 | pModel->AddUndo( std::make_unique<SdrUndoInsertObj>( *pObj ) ); | ||||||||
260 | } | ||||||||
261 | |||||||||
262 | void SAL_CALL ScChartsObj::removeByName( const OUString& aName ) | ||||||||
263 | { | ||||||||
264 | SolarMutexGuard aGuard; | ||||||||
265 | SdrOle2Obj* pObj = sc::tools::findChartsByName(pDocShell, nTab, aName, sc::tools::ChartSourceType::CELL_RANGE); | ||||||||
266 | if (pObj) | ||||||||
267 | { | ||||||||
268 | ScDocument& rDoc = pDocShell->GetDocument(); | ||||||||
269 | rDoc.GetChartListenerCollection()->removeByName(aName); | ||||||||
270 | ScDrawLayer* pModel = rDoc.GetDrawLayer(); // is not zero | ||||||||
271 | SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab)); // is not zero | ||||||||
272 | |||||||||
273 | pModel->AddUndo( std::make_unique<SdrUndoDelObj>( *pObj ) ); | ||||||||
274 | pPage->RemoveObject( pObj->GetOrdNum() ); | ||||||||
275 | |||||||||
276 | //! Notify etc.??? | ||||||||
277 | } | ||||||||
278 | } | ||||||||
279 | |||||||||
280 | // XEnumerationAccess | ||||||||
281 | |||||||||
282 | uno::Reference<container::XEnumeration> SAL_CALL ScChartsObj::createEnumeration() | ||||||||
283 | { | ||||||||
284 | SolarMutexGuard aGuard; | ||||||||
285 | return new ScIndexEnumeration(this, "com.sun.star.table.TableChartsEnumeration"); | ||||||||
286 | } | ||||||||
287 | |||||||||
288 | // XIndexAccess | ||||||||
289 | |||||||||
290 | sal_Int32 SAL_CALL ScChartsObj::getCount() | ||||||||
291 | { | ||||||||
292 | SolarMutexGuard aGuard; | ||||||||
293 | sal_Int32 nCount = 0; | ||||||||
294 | if ( pDocShell ) | ||||||||
295 | { | ||||||||
296 | ScDocument& rDoc = pDocShell->GetDocument(); | ||||||||
297 | ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer(); | ||||||||
298 | if (pDrawLayer) | ||||||||
299 | { | ||||||||
300 | SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); | ||||||||
301 | OSL_ENSURE(pPage, "Page not found")do { if (true && (!(pPage))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/unoobj/chartuno.cxx" ":" "301" ": "), "%s", "Page not found"); } } while (false); | ||||||||
302 | if (pPage) | ||||||||
303 | { | ||||||||
304 | SdrObjListIter aIter( pPage, SdrIterMode::DeepNoGroups ); | ||||||||
305 | SdrObject* pObject = aIter.Next(); | ||||||||
306 | while (pObject) | ||||||||
307 | { | ||||||||
308 | if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ScDocument::IsChart(pObject) ) | ||||||||
309 | ++nCount; | ||||||||
310 | pObject = aIter.Next(); | ||||||||
311 | } | ||||||||
312 | } | ||||||||
313 | } | ||||||||
314 | } | ||||||||
315 | return nCount; | ||||||||
316 | } | ||||||||
317 | |||||||||
318 | uno::Any SAL_CALL ScChartsObj::getByIndex( sal_Int32 nIndex ) | ||||||||
319 | { | ||||||||
320 | SolarMutexGuard aGuard; | ||||||||
321 | uno::Reference<table::XTableChart> xChart(GetObjectByIndex_Impl(nIndex)); | ||||||||
322 | if (!xChart.is()) | ||||||||
323 | throw lang::IndexOutOfBoundsException(); | ||||||||
324 | |||||||||
325 | return uno::makeAny(xChart); | ||||||||
326 | } | ||||||||
327 | |||||||||
328 | uno::Type SAL_CALL ScChartsObj::getElementType() | ||||||||
329 | { | ||||||||
330 | SolarMutexGuard aGuard; | ||||||||
331 | return cppu::UnoType<table::XTableChart>::get(); | ||||||||
332 | } | ||||||||
333 | |||||||||
334 | sal_Bool SAL_CALL ScChartsObj::hasElements() | ||||||||
335 | { | ||||||||
336 | SolarMutexGuard aGuard; | ||||||||
337 | return getCount() != 0; | ||||||||
338 | } | ||||||||
339 | |||||||||
340 | uno::Any SAL_CALL ScChartsObj::getByName( const OUString& aName ) | ||||||||
341 | { | ||||||||
342 | SolarMutexGuard aGuard; | ||||||||
343 | uno::Reference<table::XTableChart> xChart(GetObjectByName_Impl(aName)); | ||||||||
344 | if (!xChart.is()) | ||||||||
345 | throw container::NoSuchElementException(); | ||||||||
346 | |||||||||
347 | return uno::makeAny(xChart); | ||||||||
348 | } | ||||||||
349 | |||||||||
350 | uno::Sequence<OUString> SAL_CALL ScChartsObj::getElementNames() | ||||||||
351 | { | ||||||||
352 | SolarMutexGuard aGuard; | ||||||||
353 | if (pDocShell) | ||||||||
354 | { | ||||||||
355 | ScDocument& rDoc = pDocShell->GetDocument(); | ||||||||
356 | |||||||||
357 | long nCount = getCount(); | ||||||||
358 | uno::Sequence<OUString> aSeq(nCount); | ||||||||
359 | OUString* pAry = aSeq.getArray(); | ||||||||
360 | |||||||||
361 | long nPos = 0; | ||||||||
362 | ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer(); | ||||||||
363 | if (pDrawLayer) | ||||||||
364 | { | ||||||||
365 | SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); | ||||||||
366 | OSL_ENSURE(pPage, "Page not found")do { if (true && (!(pPage))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/unoobj/chartuno.cxx" ":" "366" ": "), "%s", "Page not found"); } } while (false); | ||||||||
367 | if (pPage) | ||||||||
368 | { | ||||||||
369 | SdrObjListIter aIter( pPage, SdrIterMode::DeepNoGroups ); | ||||||||
370 | SdrObject* pObject = aIter.Next(); | ||||||||
371 | while (pObject) | ||||||||
372 | { | ||||||||
373 | if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ScDocument::IsChart(pObject) ) | ||||||||
374 | { | ||||||||
375 | OUString aName; | ||||||||
376 | uno::Reference < embed::XEmbeddedObject > xObj = static_cast<SdrOle2Obj*>(pObject)->GetObjRef(); | ||||||||
377 | if ( xObj.is() ) | ||||||||
378 | aName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj ); | ||||||||
379 | |||||||||
380 | OSL_ENSURE(nPos<nCount, "oops, miscounted?")do { if (true && (!(nPos<nCount))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/unoobj/chartuno.cxx" ":" "380" ": "), "%s", "oops, miscounted?"); } } while (false ); | ||||||||
381 | pAry[nPos++] = aName; | ||||||||
382 | } | ||||||||
383 | pObject = aIter.Next(); | ||||||||
384 | } | ||||||||
385 | } | ||||||||
386 | } | ||||||||
387 | OSL_ENSURE(nPos==nCount, "hey, miscounted?")do { if (true && (!(nPos==nCount))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/unoobj/chartuno.cxx" ":" "387" ": "), "%s", "hey, miscounted?"); } } while (false ); | ||||||||
388 | |||||||||
389 | return aSeq; | ||||||||
390 | } | ||||||||
391 | return uno::Sequence<OUString>(0); | ||||||||
392 | } | ||||||||
393 | |||||||||
394 | sal_Bool SAL_CALL ScChartsObj::hasByName( const OUString& aName ) | ||||||||
395 | { | ||||||||
396 | SolarMutexGuard aGuard; | ||||||||
397 | SdrOle2Obj* aOle2Obj = sc::tools::findChartsByName(pDocShell, nTab, aName, | ||||||||
398 | sc::tools::ChartSourceType::CELL_RANGE); | ||||||||
399 | return aOle2Obj != nullptr; | ||||||||
400 | } | ||||||||
401 | |||||||||
402 | ScChartObj::ScChartObj(ScDocShell* pDocSh, SCTAB nT, const OUString& rN) | ||||||||
403 | :ScChartObj_Base( m_aMutex ) | ||||||||
404 | ,ScChartObj_PBase( ScChartObj_Base::rBHelper ) | ||||||||
405 | ,pDocShell( pDocSh ) | ||||||||
406 | ,nTab( nT ) | ||||||||
407 | ,aChartName( rN ) | ||||||||
408 | { | ||||||||
409 | pDocShell->GetDocument().AddUnoObject(*this); | ||||||||
410 | |||||||||
411 | registerPropertyNoMember( "RelatedCellRanges", | ||||||||
412 | PROP_HANDLE_RELATED_CELLRANGES1, beans::PropertyAttribute::MAYBEVOID, | ||||||||
413 | cppu::UnoType<uno::Sequence<table::CellRangeAddress>>::get(), | ||||||||
414 | css::uno::Any(uno::Sequence<table::CellRangeAddress>()) ); | ||||||||
415 | } | ||||||||
416 | |||||||||
417 | ScChartObj::~ScChartObj() | ||||||||
418 | { | ||||||||
419 | SolarMutexGuard g; | ||||||||
420 | |||||||||
421 | if (pDocShell) | ||||||||
422 | pDocShell->GetDocument().RemoveUnoObject(*this); | ||||||||
423 | } | ||||||||
424 | |||||||||
425 | void ScChartObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) | ||||||||
426 | { | ||||||||
427 | //! update reference | ||||||||
428 | |||||||||
429 | if ( rHint.GetId() == SfxHintId::Dying ) | ||||||||
430 | { | ||||||||
431 | pDocShell = nullptr; | ||||||||
432 | } | ||||||||
433 | } | ||||||||
434 | |||||||||
435 | void ScChartObj::GetData_Impl( ScRangeListRef& rRanges, bool& rColHeaders, bool& rRowHeaders ) const | ||||||||
436 | { | ||||||||
437 | bool bFound = false; | ||||||||
438 | |||||||||
439 | if( pDocShell ) | ||||||||
440 | { | ||||||||
441 | ScDocument& rDoc = pDocShell->GetDocument(); | ||||||||
442 | uno::Reference< chart2::XChartDocument > xChartDoc( rDoc.GetChartByName( aChartName ) ); | ||||||||
443 | if( xChartDoc.is() ) | ||||||||
444 | { | ||||||||
445 | uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); | ||||||||
446 | uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider(); | ||||||||
447 | if( xReceiver.is() && xProvider.is() ) | ||||||||
448 | { | ||||||||
449 | const uno::Sequence< beans::PropertyValue > aArgs( xProvider->detectArguments( xReceiver->getUsedData() ) ); | ||||||||
450 | |||||||||
451 | OUString aRanges; | ||||||||
452 | chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS; | ||||||||
453 | bool bHasCategories=false; | ||||||||
454 | bool bFirstCellAsLabel=false; | ||||||||
455 | for (const beans::PropertyValue& rProp : aArgs) | ||||||||
456 | { | ||||||||
457 | OUString aPropName(rProp.Name); | ||||||||
458 | |||||||||
459 | if (aPropName == "CellRangeRepresentation") | ||||||||
460 | rProp.Value >>= aRanges; | ||||||||
461 | else if (aPropName == "DataRowSource") | ||||||||
462 | eDataRowSource = static_cast<chart::ChartDataRowSource>(ScUnoHelpFunctions::GetEnumFromAny( rProp.Value )); | ||||||||
463 | else if (aPropName == "HasCategories") | ||||||||
464 | bHasCategories = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value ); | ||||||||
465 | else if (aPropName == "FirstCellAsLabel") | ||||||||
466 | bFirstCellAsLabel = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value ); | ||||||||
467 | } | ||||||||
468 | |||||||||
469 | if( chart::ChartDataRowSource_COLUMNS == eDataRowSource ) | ||||||||
470 | { | ||||||||
471 | rColHeaders=bFirstCellAsLabel; | ||||||||
472 | rRowHeaders=bHasCategories; | ||||||||
473 | } | ||||||||
474 | else | ||||||||
475 | { | ||||||||
476 | rColHeaders=bHasCategories; | ||||||||
477 | rRowHeaders=bFirstCellAsLabel; | ||||||||
478 | } | ||||||||
479 | rRanges->Parse( aRanges, rDoc); | ||||||||
480 | } | ||||||||
481 | bFound = true; | ||||||||
482 | } | ||||||||
483 | } | ||||||||
484 | if( !bFound
| ||||||||
485 | { | ||||||||
486 | rRanges = nullptr; | ||||||||
487 | rColHeaders = false; | ||||||||
488 | rRowHeaders = false; | ||||||||
489 | } | ||||||||
490 | } | ||||||||
491 | |||||||||
492 | void ScChartObj::Update_Impl( const ScRangeListRef& rRanges, bool bColHeaders, bool bRowHeaders ) | ||||||||
493 | { | ||||||||
494 | if (pDocShell) | ||||||||
495 | { | ||||||||
496 | ScDocument& rDoc = pDocShell->GetDocument(); | ||||||||
497 | bool bUndo(rDoc.IsUndoEnabled()); | ||||||||
498 | |||||||||
499 | if (bUndo) | ||||||||
500 | { | ||||||||
501 | pDocShell->GetUndoManager()->AddUndoAction( | ||||||||
502 | std::make_unique<ScUndoChartData>( pDocShell, aChartName, rRanges, bColHeaders, bRowHeaders, false ) ); | ||||||||
503 | } | ||||||||
504 | rDoc.UpdateChartArea( aChartName, rRanges, bColHeaders, bRowHeaders, false ); | ||||||||
505 | } | ||||||||
506 | } | ||||||||
507 | |||||||||
508 | // ::comphelper::OPropertySetHelper | ||||||||
509 | |||||||||
510 | ::cppu::IPropertyArrayHelper& ScChartObj::getInfoHelper() | ||||||||
511 | { | ||||||||
512 | return *ScChartObj_PABase::getArrayHelper(); | ||||||||
513 | } | ||||||||
514 | |||||||||
515 | void ScChartObj::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const uno::Any& rValue ) | ||||||||
516 | { | ||||||||
517 | switch ( nHandle ) | ||||||||
518 | { | ||||||||
519 | case PROP_HANDLE_RELATED_CELLRANGES1: | ||||||||
520 | { | ||||||||
521 | uno::Sequence< table::CellRangeAddress > aCellRanges; | ||||||||
522 | if ( rValue >>= aCellRanges ) | ||||||||
523 | { | ||||||||
524 | ScRangeListRef rRangeList = new ScRangeList(); | ||||||||
525 | for ( table::CellRangeAddress const & aCellRange : std::as_const(aCellRanges) ) | ||||||||
526 | { | ||||||||
527 | ScRange aRange; | ||||||||
528 | ScUnoConversion::FillScRange( aRange, aCellRange ); | ||||||||
529 | rRangeList->push_back( aRange ); | ||||||||
530 | } | ||||||||
531 | if ( pDocShell ) | ||||||||
532 | { | ||||||||
533 | ScChartListenerCollection* pCollection = pDocShell->GetDocument().GetChartListenerCollection(); | ||||||||
534 | if ( pCollection ) | ||||||||
535 | { | ||||||||
536 | pCollection->ChangeListening( aChartName, rRangeList ); | ||||||||
537 | } | ||||||||
538 | } | ||||||||
539 | } | ||||||||
540 | } | ||||||||
541 | break; | ||||||||
542 | default: | ||||||||
543 | break; | ||||||||
544 | } | ||||||||
545 | } | ||||||||
546 | |||||||||
547 | void ScChartObj::getFastPropertyValue( uno::Any& rValue, sal_Int32 nHandle ) const | ||||||||
548 | { | ||||||||
549 | switch ( nHandle ) | ||||||||
550 | { | ||||||||
551 | case PROP_HANDLE_RELATED_CELLRANGES1: | ||||||||
552 | { | ||||||||
553 | if (!pDocShell) | ||||||||
554 | break; | ||||||||
555 | ScDocument& rDoc = pDocShell->GetDocument(); | ||||||||
556 | |||||||||
557 | ScChartListenerCollection* pCollection = rDoc.GetChartListenerCollection(); | ||||||||
558 | if (!pCollection) | ||||||||
559 | break; | ||||||||
560 | |||||||||
561 | ScChartListener* pListener = pCollection->findByName(aChartName); | ||||||||
562 | if (!pListener) | ||||||||
563 | break; | ||||||||
564 | |||||||||
565 | const ScRangeListRef& rRangeList = pListener->GetRangeList(); | ||||||||
566 | if (!rRangeList.is()) | ||||||||
567 | break; | ||||||||
568 | |||||||||
569 | size_t nCount = rRangeList->size(); | ||||||||
570 | uno::Sequence<table::CellRangeAddress> aCellRanges(nCount); | ||||||||
571 | table::CellRangeAddress* pCellRanges = aCellRanges.getArray(); | ||||||||
572 | for (size_t i = 0; i < nCount; ++i) | ||||||||
573 | { | ||||||||
574 | ScRange const & rRange = (*rRangeList)[i]; | ||||||||
575 | table::CellRangeAddress aCellRange; | ||||||||
576 | ScUnoConversion::FillApiRange(aCellRange, rRange); | ||||||||
577 | pCellRanges[i] = aCellRange; | ||||||||
578 | } | ||||||||
579 | rValue <<= aCellRanges; | ||||||||
580 | } | ||||||||
581 | break; | ||||||||
582 | default: | ||||||||
583 | ; | ||||||||
584 | } | ||||||||
585 | } | ||||||||
586 | |||||||||
587 | // ::comphelper::OPropertyArrayUsageHelper | ||||||||
588 | |||||||||
589 | ::cppu::IPropertyArrayHelper* ScChartObj::createArrayHelper() const | ||||||||
590 | { | ||||||||
591 | uno::Sequence< beans::Property > aProps; | ||||||||
592 | describeProperties( aProps ); | ||||||||
593 | return new ::cppu::OPropertyArrayHelper( aProps ); | ||||||||
594 | } | ||||||||
595 | |||||||||
596 | // XInterface | ||||||||
597 | |||||||||
598 | IMPLEMENT_FORWARD_XINTERFACE2( ScChartObj, ScChartObj_Base, ScChartObj_PBase )void ScChartObj::acquire() throw() { ScChartObj_Base::acquire (); } void ScChartObj::release() throw() { ScChartObj_Base::release (); } css::uno::Any ScChartObj::queryInterface( const css::uno ::Type& _rType ) { css::uno::Any aReturn = ScChartObj_Base ::queryInterface( _rType ); if ( !aReturn.hasValue() ) aReturn = ScChartObj_PBase::queryInterface( _rType ); return aReturn ; } | ||||||||
599 | |||||||||
600 | // XTypeProvider | ||||||||
601 | |||||||||
602 | IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScChartObj, ScChartObj_Base, ScChartObj_PBase )css::uno::Sequence< css::uno::Type > ScChartObj::getTypes ( ) { return ::comphelper::concatSequences( ScChartObj_Base:: getTypes(), ScChartObj_PBase::getTypes() ); } css::uno::Sequence < sal_Int8 > ScChartObj::getImplementationId( ) { return css::uno::Sequence<sal_Int8>(); } | ||||||||
603 | |||||||||
604 | // XTableChart | ||||||||
605 | |||||||||
606 | sal_Bool SAL_CALL ScChartObj::getHasColumnHeaders() | ||||||||
607 | { | ||||||||
608 | SolarMutexGuard aGuard; | ||||||||
609 | ScRangeListRef xRanges = new ScRangeList; | ||||||||
610 | bool bColHeaders, bRowHeaders; | ||||||||
611 | GetData_Impl( xRanges, bColHeaders, bRowHeaders ); | ||||||||
612 | return bColHeaders; | ||||||||
613 | } | ||||||||
614 | |||||||||
615 | void SAL_CALL ScChartObj::setHasColumnHeaders( sal_Bool bHasColumnHeaders ) | ||||||||
616 | { | ||||||||
617 | SolarMutexGuard aGuard; | ||||||||
618 | ScRangeListRef xRanges = new ScRangeList; | ||||||||
619 | bool bOldColHeaders, bOldRowHeaders; | ||||||||
620 | GetData_Impl( xRanges, bOldColHeaders, bOldRowHeaders ); | ||||||||
621 | if ( bOldColHeaders != bool(bHasColumnHeaders) ) | ||||||||
622 | Update_Impl( xRanges, bHasColumnHeaders, bOldRowHeaders ); | ||||||||
623 | } | ||||||||
624 | |||||||||
625 | sal_Bool SAL_CALL ScChartObj::getHasRowHeaders() | ||||||||
626 | { | ||||||||
627 | SolarMutexGuard aGuard; | ||||||||
628 | ScRangeListRef xRanges = new ScRangeList; | ||||||||
629 | bool bColHeaders, bRowHeaders; | ||||||||
630 | GetData_Impl( xRanges, bColHeaders, bRowHeaders ); | ||||||||
631 | return bRowHeaders; | ||||||||
632 | } | ||||||||
633 | |||||||||
634 | void SAL_CALL ScChartObj::setHasRowHeaders( sal_Bool bHasRowHeaders ) | ||||||||
635 | { | ||||||||
636 | SolarMutexGuard aGuard; | ||||||||
637 | ScRangeListRef xRanges = new ScRangeList; | ||||||||
638 | bool bOldColHeaders, bOldRowHeaders; | ||||||||
639 | GetData_Impl( xRanges, bOldColHeaders, bOldRowHeaders ); | ||||||||
640 | if ( bOldRowHeaders != bool(bHasRowHeaders) ) | ||||||||
641 | Update_Impl( xRanges, bOldColHeaders, bHasRowHeaders ); | ||||||||
642 | } | ||||||||
643 | |||||||||
644 | uno::Sequence<table::CellRangeAddress> SAL_CALL ScChartObj::getRanges() | ||||||||
645 | { | ||||||||
646 | SolarMutexGuard aGuard; | ||||||||
647 | ScRangeListRef xRanges = new ScRangeList; | ||||||||
648 | bool bColHeaders, bRowHeaders; | ||||||||
649 | GetData_Impl( xRanges, bColHeaders, bRowHeaders ); | ||||||||
650 | if ( xRanges.is() ) | ||||||||
651 | { | ||||||||
652 | size_t nCount = xRanges->size(); | ||||||||
653 | |||||||||
654 | table::CellRangeAddress aRangeAddress; | ||||||||
655 | uno::Sequence<table::CellRangeAddress> aSeq(nCount); | ||||||||
656 | table::CellRangeAddress* pAry = aSeq.getArray(); | ||||||||
657 | for (size_t i = 0; i < nCount; i++) | ||||||||
658 | { | ||||||||
659 | ScRange const & rRange = (*xRanges)[i]; | ||||||||
660 | |||||||||
661 | aRangeAddress.Sheet = rRange.aStart.Tab(); | ||||||||
662 | aRangeAddress.StartColumn = rRange.aStart.Col(); | ||||||||
663 | aRangeAddress.StartRow = rRange.aStart.Row(); | ||||||||
664 | aRangeAddress.EndColumn = rRange.aEnd.Col(); | ||||||||
665 | aRangeAddress.EndRow = rRange.aEnd.Row(); | ||||||||
666 | |||||||||
667 | pAry[i] = aRangeAddress; | ||||||||
668 | } | ||||||||
669 | return aSeq; | ||||||||
670 | } | ||||||||
671 | |||||||||
672 | OSL_FAIL("ScChartObj::getRanges: no Ranges")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/unoobj/chartuno.cxx" ":" "672" ": "), "%s", "ScChartObj::getRanges: no Ranges"); } } while (false); | ||||||||
673 | return uno::Sequence<table::CellRangeAddress>(); | ||||||||
674 | } | ||||||||
675 | |||||||||
676 | void SAL_CALL ScChartObj::setRanges( const uno::Sequence<table::CellRangeAddress>& aRanges ) | ||||||||
677 | { | ||||||||
678 | SolarMutexGuard aGuard; | ||||||||
679 | ScRangeListRef xOldRanges = new ScRangeList; | ||||||||
680 | bool bColHeaders, bRowHeaders; | ||||||||
| |||||||||
681 | GetData_Impl( xOldRanges, bColHeaders, bRowHeaders ); | ||||||||
682 | |||||||||
683 | ScRangeList* pList = new ScRangeList; | ||||||||
684 | for (const table::CellRangeAddress& rRange : aRanges) | ||||||||
685 | { | ||||||||
686 | ScRange aRange( static_cast<SCCOL>(rRange.StartColumn), rRange.StartRow, rRange.Sheet, | ||||||||
687 | static_cast<SCCOL>(rRange.EndColumn), rRange.EndRow, rRange.Sheet ); | ||||||||
688 | pList->push_back( aRange ); | ||||||||
689 | } | ||||||||
690 | ScRangeListRef xNewRanges( pList ); | ||||||||
691 | |||||||||
692 | if ( !xOldRanges.is() || *xOldRanges != *xNewRanges ) | ||||||||
693 | Update_Impl( xNewRanges, bColHeaders, bRowHeaders ); | ||||||||
| |||||||||
694 | } | ||||||||
695 | |||||||||
696 | // XEmbeddedObjectSupplier | ||||||||
697 | |||||||||
698 | uno::Reference<lang::XComponent> SAL_CALL ScChartObj::getEmbeddedObject() | ||||||||
699 | { | ||||||||
700 | SolarMutexGuard aGuard; | ||||||||
701 | SdrOle2Obj* pObject = sc::tools::findChartsByName(pDocShell, nTab, aChartName, | ||||||||
702 | sc::tools::ChartSourceType::CELL_RANGE); | ||||||||
703 | if ( pObject && svt::EmbeddedObjectRef::TryRunningState( pObject->GetObjRef() ) ) | ||||||||
704 | { | ||||||||
705 | //TODO/LATER: is it OK that something is returned for *all* objects, not only own objects? | ||||||||
706 | return uno::Reference < lang::XComponent > ( pObject->GetObjRef()->getComponent(), uno::UNO_QUERY ); | ||||||||
707 | } | ||||||||
708 | |||||||||
709 | return nullptr; | ||||||||
710 | } | ||||||||
711 | |||||||||
712 | // XNamed | ||||||||
713 | |||||||||
714 | OUString SAL_CALL ScChartObj::getName() | ||||||||
715 | { | ||||||||
716 | SolarMutexGuard aGuard; | ||||||||
717 | return aChartName; | ||||||||
718 | } | ||||||||
719 | |||||||||
720 | void SAL_CALL ScChartObj::setName( const OUString& /* aName */ ) | ||||||||
721 | { | ||||||||
722 | SolarMutexGuard aGuard; | ||||||||
723 | throw uno::RuntimeException(); // name cannot be changed | ||||||||
724 | } | ||||||||
725 | |||||||||
726 | // XPropertySet | ||||||||
727 | |||||||||
728 | uno::Reference< beans::XPropertySetInfo > ScChartObj::getPropertySetInfo() | ||||||||
729 | { | ||||||||
730 | return createPropertySetInfo( getInfoHelper() ) ; | ||||||||
731 | } | ||||||||
732 | |||||||||
733 | /* 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: */ |