Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name chartuno.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SC_DLLIMPLEMENTATION -D SC_INFO_OSVERSION="LINUX" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/mdds/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/clew/source/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sc/source/core/inc -I /home/maarten/src/libreoffice/core/sc/source/filter/inc -I /home/maarten/src/libreoffice/core/sc/source/ui/inc -I /home/maarten/src/libreoffice/core/sc/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sc/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sc/source/ui/unoobj/chartuno.cxx

/home/maarten/src/libreoffice/core/sc/source/ui/unoobj/chartuno.cxx

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
52using namespace css;
53
54#define PROP_HANDLE_RELATED_CELLRANGES1 1
55
56SC_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; }
57SC_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
59ScChartsObj::ScChartsObj(ScDocShell* pDocSh, SCTAB nT) :
60 pDocShell( pDocSh ),
61 nTab( nT )
62{
63 pDocShell->GetDocument().AddUnoObject(*this);
64}
65
66ScChartsObj::~ScChartsObj()
67{
68 SolarMutexGuard g;
69
70 if (pDocShell)
71 pDocShell->GetDocument().RemoveUnoObject(*this);
72}
73
74void ScChartsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
75{
76 //! update reference
77
78 if ( rHint.GetId() == SfxHintId::Dying )
79 {
80 pDocShell = nullptr;
81 }
82}
83
84ScChartObj* 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
124ScChartObj* 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
133void 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
262void 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
282uno::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
290sal_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
318uno::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
328uno::Type SAL_CALL ScChartsObj::getElementType()
329{
330 SolarMutexGuard aGuard;
331 return cppu::UnoType<table::XTableChart>::get();
332}
333
334sal_Bool SAL_CALL ScChartsObj::hasElements()
335{
336 SolarMutexGuard aGuard;
337 return getCount() != 0;
338}
339
340uno::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
350uno::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
394sal_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
402ScChartObj::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
417ScChartObj::~ScChartObj()
418{
419 SolarMutexGuard g;
420
421 if (pDocShell)
422 pDocShell->GetDocument().RemoveUnoObject(*this);
423}
424
425void ScChartObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
426{
427 //! update reference
428
429 if ( rHint.GetId() == SfxHintId::Dying )
430 {
431 pDocShell = nullptr;
432 }
433}
434
435void ScChartObj::GetData_Impl( ScRangeListRef& rRanges, bool& rColHeaders, bool& rRowHeaders ) const
436{
437 bool bFound = false;
438
439 if( pDocShell )
3
Assuming field 'pDocShell' is non-null
4
Taking true branch
440 {
441 ScDocument& rDoc = pDocShell->GetDocument();
442 uno::Reference< chart2::XChartDocument > xChartDoc( rDoc.GetChartByName( aChartName ) );
443 if( xChartDoc.is() )
5
Taking true branch
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
5.1
'bFound' is true
6.1
'bFound' is true
5.1
'bFound' is true
6.1
'bFound' is true
)
6
Taking false branch
7
Taking false branch
485 {
486 rRanges = nullptr;
487 rColHeaders = false;
488 rRowHeaders = false;
489 }
490}
8
Returning without writing to 'rColHeaders'
491
492void 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
515void 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
547void 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
598IMPLEMENT_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
602IMPLEMENT_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
606sal_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
615void 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
625sal_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
634void 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
644uno::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
676void SAL_CALL ScChartObj::setRanges( const uno::Sequence<table::CellRangeAddress>& aRanges )
677{
678 SolarMutexGuard aGuard;
679 ScRangeListRef xOldRanges = new ScRangeList;
680 bool bColHeaders, bRowHeaders;
1
'bColHeaders' declared without an initial value
681 GetData_Impl( xOldRanges, bColHeaders, bRowHeaders );
2
Calling 'ScChartObj::GetData_Impl'
9
Returning from 'ScChartObj::GetData_Impl'
682
683 ScRangeList* pList = new ScRangeList;
684 for (const table::CellRangeAddress& rRange : aRanges)
10
Assuming '__begin1' is equal to '__end1'
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 )
11
Calling 'SvRef::is'
13
Returning from 'SvRef::is'
14
Assuming the condition is true
15
Taking true branch
693 Update_Impl( xNewRanges, bColHeaders, bRowHeaders );
16
2nd function call argument is an uninitialized value
694}
695
696// XEmbeddedObjectSupplier
697
698uno::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
714OUString SAL_CALL ScChartObj::getName()
715{
716 SolarMutexGuard aGuard;
717 return aChartName;
718}
719
720void SAL_CALL ScChartObj::setName( const OUString& /* aName */ )
721{
722 SolarMutexGuard aGuard;
723 throw uno::RuntimeException(); // name cannot be changed
724}
725
726// XPropertySet
727
728uno::Reference< beans::XPropertySetInfo > ScChartObj::getPropertySetInfo()
729{
730 return createPropertySetInfo( getInfoHelper() ) ;
731}
732
733/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/tools/ref.hxx

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
31namespace tools {
32
33/** T must be a class that extends SvRefBase */
34template<typename T> class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SvRef final {
35public:
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; }
12
Returning the value 1, which participates in a condition later
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
104private:
105 T * pObj;
106};
107
108/**
109 * This implements similar functionality to std::make_shared.
110 */
111template<typename T, typename... Args>
112SvRef<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 */
120class 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
128protected:
129 virtual ~SvRefBase() COVERITY_NOEXCEPT_FALSE;
130
131public:
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
171template<typename T>
172class SvCompatWeakBase;
173
174/** SvCompatWeakHdl acts as an intermediary between SvCompatWeakRef<T> and T.
175*/
176template<typename T>
177class SvCompatWeakHdl final : public SvRefBase
178{
179 friend class SvCompatWeakBase<T>;
180 T* _pObj;
181
182 SvCompatWeakHdl( T* pObj ) : _pObj( pObj ) {}
183
184public:
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*/
192template<typename T>
193class SvCompatWeakBase
194{
195 tools::SvRef< SvCompatWeakHdl<T> > _xHdl;
196
197public:
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*/
210template<typename T>
211class SAL_WARN_UNUSED__attribute__((warn_unused)) SvCompatWeakRef
212{
213 tools::SvRef< SvCompatWeakHdl<T> > _xHdl;
214public:
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: */