Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 113, column 13
Use of memory after it is freed

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 ChartController.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 -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 EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -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/chart2/source/controller/inc -I /home/maarten/src/libreoffice/core/chart2/source/inc -I /home/maarten/src/libreoffice/core/chart2/inc -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/CustomTarget/officecfg/registry -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/chart2/source/controller/main/ChartController.cxx

/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.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 <memory>
21#include <sal/config.h>
22
23#include <set>
24
25#include <ChartController.hxx>
26#include <servicenames.hxx>
27#include <ResId.hxx>
28#include <dlg_DataSource.hxx>
29#include <ChartModel.hxx>
30#include <ChartModelHelper.hxx>
31#include "ControllerCommandDispatch.hxx"
32#include <strings.hrc>
33#include <chartview/ExplicitValueProvider.hxx>
34#include <ChartViewHelper.hxx>
35
36#include <ChartWindow.hxx>
37#include <chartview/DrawModelWrapper.hxx>
38#include <DrawViewWrapper.hxx>
39#include <ObjectIdentifier.hxx>
40#include <DiagramHelper.hxx>
41#include <ControllerLockGuard.hxx>
42#include "UndoGuard.hxx"
43#include "ChartDropTargetHelper.hxx"
44
45#include <dlg_ChartType.hxx>
46#include <AccessibleChartView.hxx>
47#include "DrawCommandDispatch.hxx"
48#include "ShapeController.hxx"
49#include "UndoActions.hxx"
50#include <ViewElementListProvider.hxx>
51
52#include <cppuhelper/supportsservice.hxx>
53
54#include <com/sun/star/chart2/XChartDocument.hpp>
55#include <com/sun/star/chart2/data/XDataReceiver.hpp>
56#include <com/sun/star/frame/XController2.hpp>
57#include <com/sun/star/util/CloseVetoException.hpp>
58#include <com/sun/star/util/XModeChangeBroadcaster.hpp>
59#include <com/sun/star/util/XModifyBroadcaster.hpp>
60#include <com/sun/star/frame/LayoutManagerEvents.hpp>
61#include <com/sun/star/frame/XLayoutManagerEventBroadcaster.hpp>
62#include <com/sun/star/document/XUndoManagerSupplier.hpp>
63#include <com/sun/star/ui/XSidebar.hpp>
64#include <com/sun/star/chart2/XChartTypeContainer.hpp>
65#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
66#include <com/sun/star/chart2/XDataProviderAccess.hpp>
67
68#include <sal/log.hxx>
69#include <tools/debug.hxx>
70#include <svx/sidebar/SelectionChangeHandler.hxx>
71#include <toolkit/awt/vclxwindow.hxx>
72#include <toolkit/helper/vclunohelper.hxx>
73#include <vcl/svapp.hxx>
74#include <vcl/weld.hxx>
75#include <osl/mutex.hxx>
76
77#include <sfx2/sidebar/SidebarController.hxx>
78
79#include <com/sun/star/frame/XLayoutManager.hpp>
80
81// this is needed to properly destroy the unique_ptr to the AcceleratorExecute
82// object in the DTOR
83#include <svtools/acceleratorexecute.hxx>
84#include <svx/ActionDescriptionProvider.hxx>
85#include <tools/diagnose_ex.h>
86
87// enable the following define to let the controller listen to model changes and
88// react on this by rebuilding the view
89#define TEST_ENABLE_MODIFY_LISTENER
90
91namespace chart
92{
93
94using namespace ::com::sun::star;
95using namespace ::com::sun::star::accessibility;
96using namespace ::com::sun::star::chart2;
97using ::com::sun::star::uno::Reference;
98using ::com::sun::star::uno::Sequence;
99
100ChartController::ChartController(uno::Reference<uno::XComponentContext> const & xContext) :
101 m_aLifeTimeManager( nullptr ),
102 m_bSuspended( false ),
103 m_xCC(xContext), //@todo is it allowed to hold this context??
104 m_aModelMutex(),
105 m_aModel( nullptr, m_aModelMutex ),
106 m_xViewWindow(),
107 m_xChartView(),
108 m_pDrawModelWrapper(),
109 m_eDragMode(SdrDragMode::Move),
110 m_bWaitingForDoubleClick(false),
111 m_bWaitingForMouseUp(false),
112 m_bFieldButtonDown(false),
113 m_bConnectingToView(false),
114 m_bDisposed(false),
115 m_aDispatchContainer( m_xCC ),
116 m_eDrawMode( CHARTDRAW_SELECT ),
117 mpSelectionChangeHandler(new svx::sidebar::SelectionChangeHandler(
118 [this]() { return this->GetContextName(); },
119 this, vcl::EnumContext::Context::Cell))
120{
121 m_aDoubleClickTimer.SetInvokeHandler( LINK( this, ChartController, DoubleClickWaitingHdl )::tools::detail::makeLink( ::tools::detail::castTo<ChartController
*>(this), &ChartController::LinkStubDoubleClickWaitingHdl
)
);
122}
123
124ChartController::~ChartController()
125{
126 stopDoubleClickWaiting();
127}
128
129ChartController::TheModel::TheModel( const uno::Reference< frame::XModel > & xModel ) :
130 m_xModel( xModel ),
131 m_bOwnership( true )
132{
133 m_xCloseable =
134 uno::Reference< util::XCloseable >( xModel, uno::UNO_QUERY );
135}
136
137ChartController::TheModel::~TheModel()
138{
139}
140
141void ChartController::TheModel::addListener( ChartController* pController )
142{
143 if(m_xCloseable.is())
144 {
145 //if you need to be able to veto against the destruction of the model
146 // you must add as a close listener
147
148 //otherwise you 'can' add as closelistener or 'must' add as dispose event listener
149
150 m_xCloseable->addCloseListener(
151 static_cast<util::XCloseListener*>(pController) );
152 }
153 else if( m_xModel.is() )
154 {
155 //we need to add as dispose event listener
156 m_xModel->addEventListener(
157 static_cast<util::XCloseListener*>(pController) );
158 }
159
160}
161
162void ChartController::TheModel::removeListener( ChartController* pController )
163{
164 if(m_xCloseable.is())
165 m_xCloseable->removeCloseListener(
166 static_cast<util::XCloseListener*>(pController) );
167
168 else if( m_xModel.is() )
169 m_xModel->removeEventListener(
170 static_cast<util::XCloseListener*>(pController) );
171}
172
173void ChartController::TheModel::tryTermination()
174{
175 if(!m_bOwnership)
176 return;
177
178 try
179 {
180 if(m_xCloseable.is())
181 {
182 try
183 {
184 //@todo ? are we allowed to use sal_True here if we have the explicit ownership?
185 //I think yes, because there might be other CloseListeners later in the list which might be interested still
186 //but make sure that we do not throw the CloseVetoException here ourselves
187 //so stop listening before trying to terminate or check the source of queryclosing event
188 m_xCloseable->close(true);
189
190 m_bOwnership = false;
191 }
192 catch( const util::CloseVetoException& )
193 {
194 //since we have indicated to give up the ownership with parameter true in close call
195 //the one who has thrown the CloseVetoException is the new owner
196
197 SAL_WARN_IF( m_bOwnership, "chart2.main", "a well known owner has caught a CloseVetoException after calling close(true)")do { if (true && (m_bOwnership)) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "chart2.main")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "a well known owner has caught a CloseVetoException after calling close(true)"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("chart2.main"
), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "197" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "a well known owner has caught a CloseVetoException after calling close(true)"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "a well known owner has caught a CloseVetoException after calling close(true)"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("chart2.main"
), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "197" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "a well known owner has caught a CloseVetoException after calling close(true)"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("chart2.main"
), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "197" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "a well known owner has caught a CloseVetoException after calling close(true)"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "a well known owner has caught a CloseVetoException after calling close(true)"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("chart2.main"
), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "197" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
198 m_bOwnership = false;
199 return;
200 }
201
202 }
203 else if( m_xModel.is() )
204 {
205 //@todo correct??
206 m_xModel->dispose();
207 return;
208 }
209 }
210 catch(const uno::Exception&)
211 {
212 DBG_UNHANDLED_EXCEPTION( "chart2", "Termination of model failed" )DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "212" ": ", "chart2", "Termination of model failed" );
;
213 }
214}
215
216ChartController::TheModelRef::TheModelRef( TheModel* pTheModel, osl::Mutex& rMutex ) :
217 m_rModelMutex(rMutex)
218{
219 osl::Guard< osl::Mutex > aGuard( m_rModelMutex );
220 m_xTheModel = pTheModel;
221}
222ChartController::TheModelRef::TheModelRef( const TheModelRef& rTheModel, ::osl::Mutex& rMutex ) :
223 m_rModelMutex(rMutex)
224{
225 osl::Guard< osl::Mutex > aGuard( m_rModelMutex );
226 m_xTheModel = rTheModel.m_xTheModel;
227}
228ChartController::TheModelRef& ChartController::TheModelRef::operator=(TheModel* pTheModel)
229{
230 osl::Guard< osl::Mutex > aGuard( m_rModelMutex );
231 m_xTheModel = pTheModel;
232 return *this;
233}
234ChartController::TheModelRef& ChartController::TheModelRef::operator=(const TheModelRef& rTheModel)
235{
236 osl::Guard< osl::Mutex > aGuard( m_rModelMutex );
237 m_xTheModel = rTheModel.operator->();
238 return *this;
239}
240ChartController::TheModelRef::~TheModelRef()
241{
242 osl::Guard< osl::Mutex > aGuard( m_rModelMutex );
243 m_xTheModel.clear();
244}
245bool ChartController::TheModelRef::is() const
246{
247 return m_xTheModel.is();
248}
249
250namespace {
251
252css::uno::Reference<css::chart2::XChartType> getChartType(
253 const css::uno::Reference<css::chart2::XChartDocument>& xChartDoc)
254{
255 Reference <chart2::XDiagram > xDiagram = xChartDoc->getFirstDiagram();
256 if (!xDiagram.is()) {
257 return css::uno::Reference<css::chart2::XChartType>();
258 }
259
260 Reference< chart2::XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY_THROW );
261
262 Sequence< Reference< chart2::XCoordinateSystem > > xCooSysSequence( xCooSysContainer->getCoordinateSystems());
263 if (!xCooSysSequence.hasElements()) {
264 return css::uno::Reference<css::chart2::XChartType>();
265 }
266
267 Reference< chart2::XChartTypeContainer > xChartTypeContainer( xCooSysSequence[0], uno::UNO_QUERY_THROW );
268
269 Sequence< Reference< chart2::XChartType > > xChartTypeSequence( xChartTypeContainer->getChartTypes() );
270
271 return xChartTypeSequence[0];
272}
273
274}
275
276OUString ChartController::GetContextName()
277{
278 if (m_bDisposed)
279 return OUString();
280
281 uno::Any aAny = getSelection();
282 if (!aAny.hasValue())
283 return "Chart";
284
285 OUString aCID;
286 aAny >>= aCID;
287
288 if (aCID.isEmpty())
289 return "Chart";
290
291 ObjectType eObjectID = ObjectIdentifier::getObjectType(aCID);
292 switch (eObjectID)
293 {
294 case OBJECTTYPE_DATA_SERIES:
295 return "Series";
296 break;
297 case OBJECTTYPE_DATA_ERRORS_X:
298 case OBJECTTYPE_DATA_ERRORS_Y:
299 case OBJECTTYPE_DATA_ERRORS_Z:
300 return "ErrorBar";
301 case OBJECTTYPE_AXIS:
302 return "Axis";
303 case OBJECTTYPE_GRID:
304 return "Grid";
305 case OBJECTTYPE_DIAGRAM:
306 {
307 css::uno::Reference<css::chart2::XChartType> xChartType = getChartType(css::uno::Reference<css::chart2::XChartDocument>(getModel(), uno::UNO_QUERY));
308 if (xChartType.is() && xChartType->getChartType() == "com.sun.star.chart2.PieChartType")
309 return "ChartElements";
310 break;
311 }
312 case OBJECTTYPE_DATA_CURVE:
313 case OBJECTTYPE_DATA_AVERAGE_LINE:
314 return "Trendline";
315 default:
316 break;
317 }
318
319 return "Chart";
320}
321
322// private methods
323
324bool ChartController::impl_isDisposedOrSuspended() const
325{
326 if( m_aLifeTimeManager.impl_isDisposed() )
327 return true;
328
329 if( m_bSuspended )
330 {
331 OSL_FAIL( "This Controller is suspended" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "331" ": "), "%s", "This Controller is suspended"); } } while
(false)
;
332 return true;
333 }
334 return false;
335}
336
337// lang::XServiceInfo
338
339OUString SAL_CALL ChartController::getImplementationName()
340{
341 return CHART_CONTROLLER_SERVICE_IMPLEMENTATION_NAME"com.sun.star.comp.chart2.ChartController";
342}
343
344sal_Bool SAL_CALL ChartController::supportsService( const OUString& rServiceName )
345{
346 return cppu::supportsService(this, rServiceName);
347}
348
349css::uno::Sequence< OUString > SAL_CALL ChartController::getSupportedServiceNames()
350{
351 return {
352 CHART_CONTROLLER_SERVICE_NAME"com.sun.star.chart2.ChartController",
353 "com.sun.star.frame.Controller"
354 //// @todo : add additional services if you support any further
355 };
356}
357
358namespace {
359
360uno::Reference<ui::XSidebar> getSidebarFromModel(const uno::Reference<frame::XModel>& xModel)
361{
362 uno::Reference<container::XChild> xChild(xModel, uno::UNO_QUERY);
363 if (!xChild.is())
364 return nullptr;
365
366 uno::Reference<frame::XModel> xParent (xChild->getParent(), uno::UNO_QUERY);
367 if (!xParent.is())
368 return nullptr;
369
370 uno::Reference<frame::XController2> xController(xParent->getCurrentController(), uno::UNO_QUERY);
371 if (!xController.is())
372 return nullptr;
373
374 uno::Reference<ui::XSidebarProvider> xSidebarProvider = xController->getSidebar();
375 if (!xSidebarProvider.is())
376 return nullptr;
377
378 return xSidebarProvider->getSidebar();
379}
380
381}
382
383// XController
384
385void SAL_CALL ChartController::attachFrame(
386 const uno::Reference<frame::XFrame>& xFrame )
387{
388 SolarMutexGuard aGuard;
389
390 if( impl_isDisposedOrSuspended() ) //@todo? allow attaching the frame while suspended?
391 return; //behave passive if already disposed or suspended
392
393 mpSelectionChangeHandler->Connect();
394
395 uno::Reference<ui::XSidebar> xSidebar = getSidebarFromModel(getModel());
396 if (xSidebar.is())
397 {
398 auto pSidebar = dynamic_cast<sfx2::sidebar::SidebarController*>(xSidebar.get());
399 assert(pSidebar)(static_cast <bool> (pSidebar) ? void (0) : __assert_fail
("pSidebar", "/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
, 399, __extension__ __PRETTY_FUNCTION__))
;
400 sfx2::sidebar::SidebarController::registerSidebarForFrame(pSidebar, this);
401 pSidebar->updateModel(getModel());
402 css::lang::EventObject aEvent;
403 mpSelectionChangeHandler->selectionChanged(aEvent);
404 }
405
406 if(m_xFrame.is()) //what happens, if we do have a Frame already??
407 {
408 //@todo? throw exception?
409 OSL_FAIL( "there is already a frame attached to the controller" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "409" ": "), "%s", "there is already a frame attached to the controller"
); } } while (false)
;
410 return;
411 }
412
413 //--attach frame
414 m_xFrame = xFrame; //the frameloader is responsible to call xFrame->setComponent
415
416 //add as disposelistener to the frame (due to persistent reference) ??...:
417
418 //the frame is considered to be owner of this controller and will live longer than we do
419 //the frame or the disposer of the frame has the duty to call suspend and dispose on this object
420 //so we do not need to add as lang::XEventListener for DisposingEvents right?
421
422 //@todo nothing right???
423
424 //create view @todo is this the correct place here??
425
426 vcl::Window* pParent = nullptr;
427 //get the window parent from the frame to use as parent for our new window
428 if(xFrame.is())
429 {
430 uno::Reference< awt::XWindow > xContainerWindow = xFrame->getContainerWindow();
431 VCLXWindow* pParentComponent = comphelper::getUnoTunnelImplementation<VCLXWindow>(xContainerWindow);
432 assert(pParentComponent)(static_cast <bool> (pParentComponent) ? void (0) : __assert_fail
("pParentComponent", "/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
, 432, __extension__ __PRETTY_FUNCTION__))
;
433 if (pParentComponent)
434 pParentComponent->setVisible(true);
435
436 pParent = VCLUnoHelper::GetWindow( xContainerWindow ).get();
437 }
438
439 {
440 // calls to VCL
441 SolarMutexGuard aSolarGuard;
442 auto pChartWindow = VclPtr<ChartWindow>::Create(this,pParent,pParent?pParent->GetStyle():0);
443 pChartWindow->SetBackground();//no Background
444 m_xViewWindow.set( pChartWindow->GetComponentInterface(), uno::UNO_QUERY );
445 pChartWindow->Show();
446 m_apDropTargetHelper.reset(
447 new ChartDropTargetHelper( pChartWindow->GetDropTarget(),
448 uno::Reference< chart2::XChartDocument >( getModel(), uno::UNO_QUERY )));
449
450 impl_createDrawViewController();
451 }
452
453 //create the menu
454 {
455 uno::Reference< beans::XPropertySet > xPropSet( xFrame, uno::UNO_QUERY );
456 if( xPropSet.is() )
457 {
458 try
459 {
460 uno::Reference< css::frame::XLayoutManager > xLayoutManager;
461 xPropSet->getPropertyValue( "LayoutManager" ) >>= xLayoutManager;
462 if ( xLayoutManager.is() )
463 {
464 xLayoutManager->lock();
465 xLayoutManager->requestElement( "private:resource/menubar/menubar" );
466 //@todo: createElement should become unnecessary, remove when #i79198# is fixed
467 xLayoutManager->createElement( "private:resource/toolbar/standardbar" );
468 xLayoutManager->requestElement( "private:resource/toolbar/standardbar" );
469 //@todo: createElement should become unnecessary, remove when #i79198# is fixed
470 xLayoutManager->createElement( "private:resource/toolbar/toolbar" );
471 xLayoutManager->requestElement( "private:resource/toolbar/toolbar" );
472
473 // #i12587# support for shapes in chart
474 xLayoutManager->createElement( "private:resource/toolbar/drawbar" );
475 xLayoutManager->requestElement( "private:resource/toolbar/drawbar" );
476
477 xLayoutManager->requestElement( "private:resource/statusbar/statusbar" );
478 xLayoutManager->unlock();
479
480 // add as listener to get notified when
481 m_xLayoutManagerEventBroadcaster.set( xLayoutManager, uno::UNO_QUERY );
482 if( m_xLayoutManagerEventBroadcaster.is())
483 m_xLayoutManagerEventBroadcaster->addLayoutManagerEventListener( this );
484 }
485 }
486 catch( const uno::Exception & )
487 {
488 DBG_UNHANDLED_EXCEPTION("chart2")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "488" ": ", "chart2" );
;
489 }
490 }
491 }
492}
493
494//XModeChangeListener
495void SAL_CALL ChartController::modeChanged( const util::ModeChangeEvent& rEvent )
496{
497 SolarMutexGuard aGuard;
498 auto pChartWindow(GetChartWindow());
1
Calling 'ChartController::GetChartWindow'
20
Returning; memory was released
499 //adjust controller to view status changes
500
501 if( rEvent.NewMode == "dirty" )
21
Taking false branch
502 {
503 //the view has become dirty, we should repaint it if we have a window
504 if( pChartWindow )
505 pChartWindow->ForceInvalidate();
506 }
507 else if( rEvent.NewMode == "invalid" )
22
Taking false branch
508 {
509 //the view is about to become invalid so end all actions on it
510 impl_invalidateAccessible();
511 if( m_pDrawViewWrapper && m_pDrawViewWrapper->IsTextEdit() )
512 this->EndTextEdit();
513 if( m_pDrawViewWrapper )
514 {
515 m_pDrawViewWrapper->UnmarkAll();
516 m_pDrawViewWrapper->HideSdrPage();
517 }
518 }
519 else
520 {
521 //the view was rebuild so we can start some actions on it again
522 if( !m_bConnectingToView )
23
Assuming field 'm_bConnectingToView' is true
24
Taking false branch
523 {
524 if(pChartWindow && m_aModel.is() )
525 {
526 m_bConnectingToView = true;
527
528 GetDrawModelWrapper();
529 if(m_pDrawModelWrapper)
530 {
531 {
532 if( m_pDrawViewWrapper )
533 m_pDrawViewWrapper->ReInit();
534 }
535
536 //reselect object
537 if( m_aSelection.hasSelection() )
538 this->impl_selectObjectAndNotiy();
539 else
540 ChartModelHelper::triggerRangeHighlighting( getModel() );
541
542 impl_initializeAccessible();
543
544 {
545 if( pChartWindow )
546 pChartWindow->Invalidate();
547 }
548 }
549
550 m_bConnectingToView = false;
551 }
552 }
553 }
554}
25
Calling implicit destructor for 'VclPtr<chart::ChartWindow>'
26
Calling '~Reference'
555
556sal_Bool SAL_CALL ChartController::attachModel( const uno::Reference< frame::XModel > & xModel )
557{
558 impl_invalidateAccessible();
559
560 //is called to attach the controller to a new model.
561 //return true if attach was successfully, false otherwise (e.g. if you do not work with a model)
562
563 SolarMutexResettableGuard aGuard;
564 if( impl_isDisposedOrSuspended() ) //@todo? allow attaching a new model while suspended?
565 return false; //behave passive if already disposed or suspended
566 aGuard.clear();
567
568 TheModelRef aNewModelRef( new TheModel( xModel), m_aModelMutex);
569 TheModelRef aOldModelRef(m_aModel,m_aModelMutex);
570 m_aModel = aNewModelRef;
571
572 //--handle relations to the old model if any
573 if( aOldModelRef.is() )
574 {
575 uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY );
576 if( xViewBroadcaster.is() )
577 xViewBroadcaster->removeModeChangeListener(this);
578 m_pDrawModelWrapper.reset();
579
580 aOldModelRef->removeListener( this );
581 #ifdef TEST_ENABLE_MODIFY_LISTENER
582 uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aOldModelRef->getModel(),uno::UNO_QUERY );
583 if( xMBroadcaster.is())
584 xMBroadcaster->removeModifyListener( this );
585#endif
586 }
587
588 //--handle relations to the new model
589 aNewModelRef->addListener( this );
590
591 aGuard.reset(); // lock for m_aDispatchContainer access
592 // set new model at dispatchers
593 m_aDispatchContainer.setModel( aNewModelRef->getModel());
594 ControllerCommandDispatch * pDispatch = new ControllerCommandDispatch( m_xCC, this, &m_aDispatchContainer );
595 pDispatch->initialize();
596
597 // the dispatch container will return "this" for all commands returned by
598 // impl_getAvailableCommands(). That means, for those commands dispatch()
599 // is called here at the ChartController.
600 m_aDispatchContainer.setChartDispatch( pDispatch, impl_getAvailableCommands() );
601
602 DrawCommandDispatch* pDrawDispatch = new DrawCommandDispatch( m_xCC, this );
603 pDrawDispatch->initialize();
604 m_aDispatchContainer.setDrawCommandDispatch( pDrawDispatch );
605
606 ShapeController* pShapeController = new ShapeController( m_xCC, this );
607 pShapeController->initialize();
608 m_aDispatchContainer.setShapeController( pShapeController );
609 aGuard.clear();
610
611#ifdef TEST_ENABLE_MODIFY_LISTENER
612 uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aNewModelRef->getModel(),uno::UNO_QUERY );
613 if( xMBroadcaster.is())
614 xMBroadcaster->addModifyListener( this );
615#endif
616
617 // #i119999# Do not do this per default to allow the user to deselect the chart OLE with a single press to ESC
618 // select chart area per default:
619 // select( uno::Any( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) ) );
620
621 uno::Reference< lang::XMultiServiceFactory > xFact( getModel(), uno::UNO_QUERY );
622 if( xFact.is())
623 {
624 m_xChartView = xFact->createInstance( CHART_VIEW_SERVICE_NAME"com.sun.star.chart2.ChartView" );
625 GetDrawModelWrapper();
626 uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY );
627 if( xViewBroadcaster.is() )
628 xViewBroadcaster->addModeChangeListener(this);
629 }
630
631 //the frameloader is responsible to call xModel->connectController
632 {
633 SolarMutexGuard aGuard2;
634 auto pChartWindow(GetChartWindow());
635 if( pChartWindow )
636 pChartWindow->Invalidate();
637 }
638
639 uno::Reference< document::XUndoManagerSupplier > xSuppUndo( getModel(), uno::UNO_QUERY_THROW );
640 m_xUndoManager.set( xSuppUndo->getUndoManager(), uno::UNO_SET_THROW );
641
642 return true;
643}
644
645uno::Reference< frame::XFrame > SAL_CALL ChartController::getFrame()
646{
647 //provides access to owner frame of this controller
648 //return the frame containing this controller
649
650 return m_xFrame;
651}
652
653uno::Reference< frame::XModel > SAL_CALL ChartController::getModel()
654{
655 //provides access to currently attached model
656 //returns the currently attached model
657
658 //return nothing, if you do not have a model
659 TheModelRef aModelRef( m_aModel, m_aModelMutex);
660 if(aModelRef.is())
661 return aModelRef->getModel();
662
663 return uno::Reference< frame::XModel > ();
664}
665
666uno::Any SAL_CALL ChartController::getViewData()
667{
668 //provides access to current view status
669 //set of data that can be used to restore the current view status at later time
670 // by using XController::restoreViewData()
671
672 SolarMutexGuard aGuard;
673 if( impl_isDisposedOrSuspended() )
674 return uno::Any(); //behave passive if already disposed or suspended //@todo? or throw an exception??
675
676 //-- collect current view state
677 uno::Any aRet;
678 //// @todo integrate specialized implementation
679
680 return aRet;
681}
682
683void SAL_CALL ChartController::restoreViewData(
684 const uno::Any& /* Value */ )
685{
686 //restores the view status using the data gotten from a previous call to XController::getViewData()
687
688 SolarMutexGuard aGuard;
689 if( impl_isDisposedOrSuspended() )
690 return; //behave passive if already disposed or suspended //@todo? or throw an exception??
691
692 //// @todo integrate specialized implementation
693}
694
695sal_Bool SAL_CALL ChartController::suspend( sal_Bool bSuspend )
696{
697 //is called to prepare the controller for closing the view
698 //bSuspend==true: force the controller to suspend his work
699 //bSuspend==false try to reactivate the controller
700 //returns true if request was accepted and of course successfully finished, false otherwise
701
702 //we may show dialogs here to ask the user for saving changes ... @todo?
703
704 SolarMutexGuard aGuard;
705 if( m_aLifeTimeManager.impl_isDisposed() )
706 return false; //behave passive if already disposed, return false because request was not accepted //@todo? correct
707
708 if(bool(bSuspend) == m_bSuspended)
709 {
710 OSL_FAIL( "new suspend mode equals old suspend mode" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "710" ": "), "%s", "new suspend mode equals old suspend mode"
); } } while (false)
;
711 return true;
712 }
713
714 //change suspend mode
715 m_bSuspended = bSuspend;
716 return true;
717}
718
719void ChartController::impl_createDrawViewController()
720{
721 SolarMutexGuard aGuard;
722 if(!m_pDrawViewWrapper)
723 {
724 if( m_pDrawModelWrapper )
725 {
726 m_pDrawViewWrapper.reset( new DrawViewWrapper(m_pDrawModelWrapper->getSdrModel(),GetChartWindow()) );
727 m_pDrawViewWrapper->attachParentReferenceDevice( getModel() );
728 }
729 }
730}
731
732void ChartController::impl_deleteDrawViewController()
733{
734 if( m_pDrawViewWrapper )
735 {
736 SolarMutexGuard aGuard;
737 if( m_pDrawViewWrapper->IsTextEdit() )
738 this->EndTextEdit();
739 m_pDrawViewWrapper.reset();
740 }
741}
742
743// XComponent (base of XController)
744
745void SAL_CALL ChartController::dispose()
746{
747 m_bDisposed = true;
748
749 if (getModel().is())
750 {
751 uno::Reference<ui::XSidebar> xSidebar = getSidebarFromModel(getModel());
752 if (sfx2::sidebar::SidebarController* pSidebar = dynamic_cast<sfx2::sidebar::SidebarController*>(xSidebar.get()))
753 {
754 sfx2::sidebar::SidebarController::unregisterSidebarForFrame(pSidebar, this);
755 }
756 }
757 mpSelectionChangeHandler->selectionChanged(css::lang::EventObject());
758 mpSelectionChangeHandler->Disconnect();
759
760 try
761 {
762 //This object should release all resources and references in the
763 //easiest possible manner
764 //This object must notify all registered listeners using the method
765 //<member>XEventListener::disposing</member>
766
767 //hold no mutex
768 if( !m_aLifeTimeManager.dispose() )
769 return;
770
771// OSL_ENSURE( m_bSuspended, "dispose was called but controller is not suspended" );
772
773 this->stopDoubleClickWaiting();
774
775 //end range highlighting
776 if( m_aModel.is())
777 {
778 uno::Reference< view::XSelectionChangeListener > xSelectionChangeListener;
779 uno::Reference< chart2::data::XDataReceiver > xDataReceiver( getModel(), uno::UNO_QUERY );
780 if( xDataReceiver.is() )
781 xSelectionChangeListener.set( xDataReceiver->getRangeHighlighter(), uno::UNO_QUERY );
782 if( xSelectionChangeListener.is() )
783 {
784 uno::Reference< frame::XController > xController( this );
785 lang::EventObject aEvent( xController );
786 xSelectionChangeListener->disposing( aEvent );
787 }
788 }
789
790 //--release all resources and references
791 {
792 uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY );
793 if( xViewBroadcaster.is() )
794 xViewBroadcaster->removeModeChangeListener(this);
795
796 impl_invalidateAccessible();
797 SolarMutexGuard aSolarGuard;
798 impl_deleteDrawViewController();
799 m_pDrawModelWrapper.reset();
800
801 m_apDropTargetHelper.reset();
802
803 //the accessible view is disposed within window destructor of m_pChartWindow
804 if(m_xViewWindow.is())
805 m_xViewWindow->dispose(); //ChartWindow is deleted via UNO due to dispose of m_xViewWindow (triggered by Framework (Controller pretends to be XWindow also))
806 m_xChartView.clear();
807 }
808
809 // remove as listener to layout manager events
810 if( m_xLayoutManagerEventBroadcaster.is())
811 {
812 m_xLayoutManagerEventBroadcaster->removeLayoutManagerEventListener( this );
813 m_xLayoutManagerEventBroadcaster.set( nullptr );
814 }
815
816 m_xFrame.clear();
817 m_xUndoManager.clear();
818
819 TheModelRef aModelRef( m_aModel, m_aModelMutex);
820 m_aModel = nullptr;
821
822 if( aModelRef.is())
823 {
824 uno::Reference< frame::XModel > xModel( aModelRef->getModel() );
825 if(xModel.is())
826 xModel->disconnectController( uno::Reference< frame::XController >( this ));
827
828 aModelRef->removeListener( this );
829#ifdef TEST_ENABLE_MODIFY_LISTENER
830 try
831 {
832 uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aModelRef->getModel(),uno::UNO_QUERY );
833 if( xMBroadcaster.is())
834 xMBroadcaster->removeModifyListener( this );
835 }
836 catch( const uno::Exception & )
837 {
838 DBG_UNHANDLED_EXCEPTION("chart2")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "838" ": ", "chart2" );
;
839 }
840#endif
841 aModelRef->tryTermination();
842 }
843
844 //// @todo integrate specialized implementation
845 //e.g. release further resources and references
846
847 SolarMutexGuard g;
848 m_aDispatchContainer.DisposeAndClear();
849 }
850 catch( const uno::Exception & )
851 {
852 DBG_UNHANDLED_EXCEPTION("chart2")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "852" ": ", "chart2" );
;
853 assert(!m_xChartView.is())(static_cast <bool> (!m_xChartView.is()) ? void (0) : __assert_fail
("!m_xChartView.is()", "/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
, 853, __extension__ __PRETTY_FUNCTION__))
;
854 }
855 }
856
857void SAL_CALL ChartController::addEventListener(
858 const uno::Reference<lang::XEventListener>& xListener )
859{
860 SolarMutexGuard aGuard;
861 if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode?
862 return; //behave passive if already disposed or suspended
863
864 //--add listener
865 m_aLifeTimeManager.m_aListenerContainer.addInterface( cppu::UnoType<lang::XEventListener>::get(), xListener );
866}
867
868void SAL_CALL ChartController::removeEventListener(
869 const uno::Reference<lang::XEventListener>& xListener )
870{
871 SolarMutexGuard aGuard;
872 if( m_aLifeTimeManager.impl_isDisposed(false) )
873 return; //behave passive if already disposed or suspended
874
875 //--remove listener
876 m_aLifeTimeManager.m_aListenerContainer.removeInterface( cppu::UnoType<lang::XEventListener>::get(), xListener );
877}
878
879// util::XCloseListener
880void SAL_CALL ChartController::queryClosing(
881 const lang::EventObject& rSource,
882 sal_Bool /*bGetsOwnership*/ )
883{
884 //do not use the m_aControllerMutex here because this call is not allowed to block
885
886 TheModelRef aModelRef( m_aModel, m_aModelMutex);
887
888 if( !aModelRef.is() )
889 return;
890
891 if( aModelRef->getModel() != rSource.Source )
892 {
893 OSL_FAIL( "queryClosing was called on a controller from an unknown source" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "893" ": "), "%s", "queryClosing was called on a controller from an unknown source"
); } } while (false)
;
894 return;
895 }
896
897 //@ todo prepare to closing model -> don't start any further hindering actions
898}
899
900void SAL_CALL ChartController::notifyClosing(
901 const lang::EventObject& rSource )
902{
903 //Listener should deregister himself and release all references to the closing object.
904
905 TheModelRef aModelRef( m_aModel, m_aModelMutex);
906 if( !impl_releaseThisModel( rSource.Source ) )
907 return;
908
909 //--stop listening to the closing model
910 aModelRef->removeListener( this );
911
912 // #i79087# If the model using this controller is closed, the frame is
913 // expected to be closed as well
914 Reference< util::XCloseable > xFrameCloseable( m_xFrame, uno::UNO_QUERY );
915 if( xFrameCloseable.is())
916 {
917 try
918 {
919 xFrameCloseable->close( false /* DeliverOwnership */ );
920 m_xFrame.clear();
921 }
922 catch( const util::CloseVetoException & )
923 {
924 // closing was vetoed
925 }
926 }
927}
928
929bool ChartController::impl_releaseThisModel(
930 const uno::Reference< uno::XInterface > & xModel )
931{
932 bool bReleaseModel = false;
933 {
934 ::osl::Guard< ::osl::Mutex > aGuard( m_aModelMutex );
935 if( m_aModel.is() && m_aModel->getModel() == xModel )
936 {
937 m_aModel = nullptr;
938 m_xUndoManager.clear();
939 bReleaseModel = true;
940 }
941 }
942 if( bReleaseModel )
943 {
944 SolarMutexGuard g;
945 m_aDispatchContainer.setModel( nullptr );
946 }
947 return bReleaseModel;
948}
949
950// util::XEventListener (base of XCloseListener)
951void SAL_CALL ChartController::disposing(
952 const lang::EventObject& rSource )
953{
954 if( !impl_releaseThisModel( rSource.Source ))
955 {
956 if( rSource.Source == m_xLayoutManagerEventBroadcaster )
957 m_xLayoutManagerEventBroadcaster.set( nullptr );
958 }
959}
960
961void SAL_CALL ChartController::layoutEvent(
962 const lang::EventObject& aSource,
963 sal_Int16 eLayoutEvent,
964 const uno::Any& /* aInfo */ )
965{
966 if( eLayoutEvent == frame::LayoutManagerEvents::MERGEDMENUBAR )
967 {
968 Reference< frame::XLayoutManager > xLM( aSource.Source, uno::UNO_QUERY );
969 if( xLM.is())
970 {
971 xLM->createElement( "private:resource/statusbar/statusbar" );
972 xLM->requestElement( "private:resource/statusbar/statusbar" );
973 }
974 }
975}
976
977// XDispatchProvider (required interface)
978
979namespace
980{
981
982bool lcl_isFormatObjectCommand( const OUString& aCommand )
983{
984 return aCommand == "MainTitle"
985 || aCommand == "SubTitle"
986 || aCommand == "XTitle"
987 || aCommand == "YTitle"
988 || aCommand == "ZTitle"
989 || aCommand == "SecondaryXTitle"
990 || aCommand == "SecondaryYTitle"
991 || aCommand == "AllTitles"
992 || aCommand == "DiagramAxisX"
993 || aCommand == "DiagramAxisY"
994 || aCommand == "DiagramAxisZ"
995 || aCommand == "DiagramAxisA"
996 || aCommand == "DiagramAxisB"
997 || aCommand == "DiagramAxisAll"
998 || aCommand == "DiagramGridXMain"
999 || aCommand == "DiagramGridYMain"
1000 || aCommand == "DiagramGridZMain"
1001 || aCommand == "DiagramGridXHelp"
1002 || aCommand == "DiagramGridYHelp"
1003 || aCommand == "DiagramGridZHelp"
1004 || aCommand == "DiagramGridAll"
1005
1006 || aCommand == "DiagramWall"
1007 || aCommand == "DiagramFloor"
1008 || aCommand == "DiagramArea"
1009 || aCommand == "Legend"
1010
1011 || aCommand == "FormatWall"
1012 || aCommand == "FormatFloor"
1013 || aCommand == "FormatChartArea"
1014 || aCommand == "FormatLegend"
1015
1016 || aCommand == "FormatTitle"
1017 || aCommand == "FormatAxis"
1018 || aCommand == "FormatDataSeries"
1019 || aCommand == "FormatDataPoint"
1020 || aCommand == "FormatDataLabels"
1021 || aCommand == "FormatDataLabel"
1022 || aCommand == "FormatXErrorBars"
1023 || aCommand == "FormatYErrorBars"
1024 || aCommand == "FormatMeanValue"
1025 || aCommand == "FormatTrendline"
1026 || aCommand == "FormatTrendlineEquation"
1027 || aCommand == "FormatStockLoss"
1028 || aCommand == "FormatStockGain"
1029 || aCommand == "FormatMajorGrid"
1030 || aCommand == "FormatMinorGrid";
1031}
1032
1033} // anonymous namespace
1034
1035uno::Reference<frame::XDispatch> SAL_CALL
1036 ChartController::queryDispatch(
1037 const util::URL& rURL,
1038 const OUString& rTargetFrameName,
1039 sal_Int32 /* nSearchFlags */)
1040{
1041 SolarMutexGuard aGuard;
1042
1043 if ( !m_aLifeTimeManager.impl_isDisposed() && getModel().is() )
1044 {
1045 if( !rTargetFrameName.isEmpty() && rTargetFrameName == "_self" )
1046 return m_aDispatchContainer.getDispatchForURL( rURL );
1047 }
1048 return uno::Reference< frame::XDispatch > ();
1049}
1050
1051uno::Sequence<uno::Reference<frame::XDispatch > >
1052 ChartController::queryDispatches(
1053 const uno::Sequence<frame::DispatchDescriptor>& xDescripts )
1054{
1055 SolarMutexGuard g;
1056
1057 if ( !m_aLifeTimeManager.impl_isDisposed() )
1058 {
1059 return m_aDispatchContainer.getDispatchesForURLs( xDescripts );
1060 }
1061 return uno::Sequence<uno::Reference<frame::XDispatch > > ();
1062}
1063
1064// frame::XDispatch
1065
1066void SAL_CALL ChartController::dispatch(
1067 const util::URL& rURL,
1068 const uno::Sequence< beans::PropertyValue >& rArgs )
1069{
1070 OUString aCommand = rURL.Path;
1071
1072 if(aCommand == "LOKSetTextSelection")
1073 {
1074 if (rArgs.getLength() == 3)
1075 {
1076 sal_Int32 nType = -1;
1077 rArgs[0].Value >>= nType;
1078 sal_Int32 nX = 0;
1079 rArgs[1].Value >>= nX;
1080 sal_Int32 nY = 0;
1081 rArgs[2].Value >>= nY;
1082 executeDispatch_LOKSetTextSelection(nType, nX, nY);
1083 }
1084 }
1085 else if (aCommand == "LOKTransform")
1086 {
1087 if (rArgs[0].Name == "Action")
1088 {
1089 OUString sAction;
1090 if ((rArgs[0].Value >>= sAction) && sAction == "PieSegmentDragging")
1091 {
1092 if (rArgs[1].Name == "Offset")
1093 {
1094 sal_Int32 nOffset;
1095 if (rArgs[1].Value >>= nOffset)
1096 {
1097 this->executeDispatch_LOKPieSegmentDragging(nOffset);
1098 }
1099 }
1100 }
1101 }
1102 else
1103 {
1104 this->executeDispatch_PositionAndSize(&rArgs);
1105 }
1106 }
1107 else if(aCommand == "FillColor")
1108 {
1109 if (rArgs.getLength() > 0)
1110 {
1111 sal_uInt32 nColor;
1112 rArgs[0].Value >>= nColor;
1113 this->executeDispatch_FillColor(nColor);
1114 }
1115 }
1116 else if(aCommand == "Paste")
1117 this->executeDispatch_Paste();
1118 else if(aCommand == "Copy" )
1119 this->executeDispatch_Copy();
1120 else if(aCommand == "Cut" )
1121 this->executeDispatch_Cut();
1122 else if(aCommand == "DataRanges" )
1123 this->executeDispatch_SourceData();
1124 else if(aCommand == "Update" ) //Update Chart
1125 {
1126 ChartViewHelper::setViewToDirtyState( getModel() );
1127 SolarMutexGuard aGuard;
1128 auto pChartWindow(GetChartWindow());
1129 if( pChartWindow )
1130 pChartWindow->Invalidate();
1131 }
1132 else if(aCommand == "DiagramData" )
1133 this->executeDispatch_EditData();
1134 //insert objects
1135 else if( aCommand == "InsertTitles"
1136 || aCommand == "InsertMenuTitles")
1137 this->executeDispatch_InsertTitles();
1138 else if( aCommand == "InsertMenuLegend" )
1139 this->executeDispatch_OpenLegendDialog();
1140 else if( aCommand == "InsertLegend" )
1141 this->executeDispatch_InsertLegend();
1142 else if( aCommand == "DeleteLegend" )
1143 this->executeDispatch_DeleteLegend();
1144 else if( aCommand == "InsertMenuDataLabels" )
1145 this->executeDispatch_InsertMenu_DataLabels();
1146 else if( aCommand == "InsertMenuAxes"
1147 || aCommand == "InsertRemoveAxes" )
1148 this->executeDispatch_InsertAxes();
1149 else if( aCommand == "InsertMenuGrids" )
1150 this->executeDispatch_InsertGrid();
1151 else if( aCommand == "InsertMenuTrendlines" )
1152 this->executeDispatch_InsertMenu_Trendlines();
1153 else if( aCommand == "InsertMenuMeanValues" )
1154 this->executeDispatch_InsertMenu_MeanValues();
1155 else if( aCommand == "InsertMenuXErrorBars" )
1156 this->executeDispatch_InsertErrorBars(false);
1157 else if( aCommand == "InsertMenuYErrorBars" )
1158 this->executeDispatch_InsertErrorBars(true);
1159 else if( aCommand == "InsertSymbol" )
1160 this->executeDispatch_InsertSpecialCharacter();
1161 else if( aCommand == "InsertTrendline" )
1162 this->executeDispatch_InsertTrendline();
1163 else if( aCommand == "DeleteTrendline" )
1164 this->executeDispatch_DeleteTrendline();
1165 else if( aCommand == "InsertMeanValue" )
1166 this->executeDispatch_InsertMeanValue();
1167 else if( aCommand == "DeleteMeanValue" )
1168 this->executeDispatch_DeleteMeanValue();
1169 else if( aCommand == "InsertXErrorBars" )
1170 this->executeDispatch_InsertErrorBars(false);
1171 else if( aCommand == "InsertYErrorBars" )
1172 this->executeDispatch_InsertErrorBars(true);
1173 else if( aCommand == "DeleteXErrorBars" )
1174 this->executeDispatch_DeleteErrorBars(false);
1175 else if( aCommand == "DeleteYErrorBars" )
1176 this->executeDispatch_DeleteErrorBars(true);
1177 else if( aCommand == "InsertTrendlineEquation" )
1178 this->executeDispatch_InsertTrendlineEquation();
1179 else if( aCommand == "DeleteTrendlineEquation" )
1180 this->executeDispatch_DeleteTrendlineEquation();
1181 else if( aCommand == "InsertTrendlineEquationAndR2" )
1182 this->executeDispatch_InsertTrendlineEquation( true );
1183 else if( aCommand == "InsertR2Value" )
1184 this->executeDispatch_InsertR2Value();
1185 else if( aCommand == "DeleteR2Value")
1186 this->executeDispatch_DeleteR2Value();
1187 else if( aCommand == "InsertDataLabels" )
1188 this->executeDispatch_InsertDataLabels();
1189 else if( aCommand == "InsertDataLabel" )
1190 this->executeDispatch_InsertDataLabel();
1191 else if( aCommand == "DeleteDataLabels")
1192 this->executeDispatch_DeleteDataLabels();
1193 else if( aCommand == "DeleteDataLabel" )
1194 this->executeDispatch_DeleteDataLabel();
1195 else if( aCommand == "ResetAllDataPoints" )
1196 this->executeDispatch_ResetAllDataPoints();
1197 else if( aCommand == "ResetDataPoint" )
1198 this->executeDispatch_ResetDataPoint();
1199 else if( aCommand == "InsertAxis" )
1200 this->executeDispatch_InsertAxis();
1201 else if( aCommand == "InsertMajorGrid" )
1202 this->executeDispatch_InsertMajorGrid();
1203 else if( aCommand == "InsertMinorGrid" )
1204 this->executeDispatch_InsertMinorGrid();
1205 else if( aCommand == "InsertAxisTitle" )
1206 this->executeDispatch_InsertAxisTitle();
1207 else if( aCommand == "DeleteAxis" )
1208 this->executeDispatch_DeleteAxis();
1209 else if( aCommand == "DeleteMajorGrid")
1210 this->executeDispatch_DeleteMajorGrid();
1211 else if( aCommand == "DeleteMinorGrid" )
1212 this->executeDispatch_DeleteMinorGrid();
1213 //format objects
1214 else if( aCommand == "FormatSelection" )
1215 this->executeDispatch_ObjectProperties();
1216 else if( aCommand == "TransformDialog" )
1217 {
1218 if ( isShapeContext() )
1219 {
1220 this->impl_ShapeControllerDispatch( rURL, rArgs );
1221 }
1222 else
1223 {
1224 this->executeDispatch_PositionAndSize();
1225 }
1226 }
1227 else if( lcl_isFormatObjectCommand(aCommand) )
1228 this->executeDispatch_FormatObject(rURL.Path);
1229 //more format
1230 else if( aCommand == "DiagramType" )
1231 this->executeDispatch_ChartType();
1232 else if( aCommand == "View3D" )
1233 this->executeDispatch_View3D();
1234 else if ( aCommand == "Forward" )
1235 {
1236 if ( isShapeContext() )
1237 {
1238 this->impl_ShapeControllerDispatch( rURL, rArgs );
1239 }
1240 else
1241 {
1242 this->executeDispatch_MoveSeries( true );
1243 }
1244 }
1245 else if ( aCommand == "Backward" )
1246 {
1247 if ( isShapeContext() )
1248 {
1249 this->impl_ShapeControllerDispatch( rURL, rArgs );
1250 }
1251 else
1252 {
1253 this->executeDispatch_MoveSeries( false );
1254 }
1255 }
1256 else if( aCommand == "NewArrangement")
1257 this->executeDispatch_NewArrangement();
1258 else if( aCommand == "ToggleLegend" )
1259 this->executeDispatch_ToggleLegend();
1260 else if( aCommand == "ToggleGridHorizontal" )
1261 this->executeDispatch_ToggleGridHorizontal();
1262 else if( aCommand == "ToggleGridVertical" )
1263 this->executeDispatch_ToggleGridVertical();
1264 else if( aCommand == "ScaleText" )
1265 this->executeDispatch_ScaleText();
1266 else if( aCommand == "StatusBarVisible" )
1267 {
1268 // workaround: this should not be necessary.
1269 uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY );
1270 if( xPropSet.is() )
1271 {
1272 uno::Reference< css::frame::XLayoutManager > xLayoutManager;
1273 xPropSet->getPropertyValue( "LayoutManager" ) >>= xLayoutManager;
1274 if ( xLayoutManager.is() )
1275 {
1276 bool bIsVisible( xLayoutManager->isElementVisible( "private:resource/statusbar/statusbar" ));
1277 if( bIsVisible )
1278 {
1279 xLayoutManager->hideElement( "private:resource/statusbar/statusbar" );
1280 xLayoutManager->destroyElement( "private:resource/statusbar/statusbar" );
1281 }
1282 else
1283 {
1284 xLayoutManager->createElement( "private:resource/statusbar/statusbar" );
1285 xLayoutManager->showElement( "private:resource/statusbar/statusbar" );
1286 }
1287 // @todo: update menu state (checkmark next to "Statusbar").
1288 }
1289 }
1290 }
1291}
1292
1293void SAL_CALL ChartController::addStatusListener(
1294 const uno::Reference<frame::XStatusListener >& /* xControl */,
1295 const util::URL& /* aURL */ )
1296{
1297 //@todo
1298}
1299
1300void SAL_CALL ChartController::removeStatusListener(
1301 const uno::Reference<frame::XStatusListener >& /* xControl */,
1302 const util::URL& /* aURL */ )
1303{
1304 //@todo
1305}
1306
1307// XContextMenuInterception (optional interface)
1308void SAL_CALL ChartController::registerContextMenuInterceptor(
1309 const uno::Reference< ui::XContextMenuInterceptor >& /* xInterceptor */)
1310{
1311 //@todo
1312}
1313
1314void SAL_CALL ChartController::releaseContextMenuInterceptor(
1315 const uno::Reference< ui::XContextMenuInterceptor > & /* xInterceptor */)
1316{
1317 //@todo
1318}
1319
1320// ____ XEmbeddedClient ____
1321// implementation see: ChartController_EditData.cxx
1322
1323void ChartController::executeDispatch_ChartType()
1324{
1325 UndoLiveUpdateGuard aUndoGuard(
1326 SchResId( STR_ACTION_EDIT_CHARTTYPEreinterpret_cast<char const *>("STR_ACTION_EDIT_CHARTTYPE"
"\004" u8"Edit chart type")
), m_xUndoManager );
1327
1328 SolarMutexGuard aSolarGuard;
1329 //prepare and open dialog
1330 ChartTypeDialog aDlg(GetChartFrame(), getModel());
1331 if (aDlg.run() == RET_OK)
1332 {
1333 impl_adaptDataSeriesAutoResize();
1334 aUndoGuard.commit();
1335 }
1336}
1337
1338void ChartController::executeDispatch_SourceData()
1339{
1340 //convert properties to ItemSet
1341 uno::Reference< XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
1342 OSL_ENSURE( xChartDoc.is(), "Invalid XChartDocument" )do { if (true && (!(xChartDoc.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "1342" ": "), "%s", "Invalid XChartDocument"); } } while
(false)
;
1343 if( !xChartDoc.is() )
1344 return;
1345
1346 // If there is a data table we should ask user if we really want to destroy it
1347 // and switch to data ranges.
1348 ChartModel& rModel = dynamic_cast<ChartModel&>(*xChartDoc);
1349 if ( rModel.hasInternalDataProvider() )
1350 {
1351 // Check if we will able to create data provider later
1352 css::uno::Reference< com::sun::star::chart2::XDataProviderAccess > xCreatorDoc(
1353 rModel.getParent(), uno::UNO_QUERY);
1354 if (!xCreatorDoc.is())
1355 return;
1356
1357 SolarMutexGuard aSolarGuard;
1358
1359 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetChartFrame(),
1360 VclMessageType::Question, VclButtonsType::YesNo, SchResId(STR_DLG_REMOVE_DATA_TABLEreinterpret_cast<char const *>("STR_DLG_REMOVE_DATA_TABLE"
"\004" u8"This chart currently contains an internal data table. Do you want to proceed, deleting the internal data table, and set a new data range?"
)
)));
1361 // If "No" then just return
1362 if (xQueryBox->run() == RET_NO)
1363 return;
1364
1365 // Remove data table
1366 rModel.removeDataProviders();
1367
1368 // Ask parent document to create new data provider
1369
1370 uno::Reference< data::XDataProvider > xDataProvider = xCreatorDoc->createDataProvider();
1371 SAL_WARN_IF( !xDataProvider.is(), "chart2.main", "Data provider was not created" )do { if (true && (!xDataProvider.is())) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "chart2.main")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "Data provider was not created"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("chart2.main"
), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "1371" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Data provider was not created"), 0)
; } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Data provider was not created"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("chart2.main"), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "1371" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Data provider was not created") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("chart2.main"), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "1371" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Data provider was not created"), 0)
; } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Data provider was not created"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("chart2.main"), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "1371" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1372 if (xDataProvider.is())
1373 {
1374 rModel.attachDataProvider(xDataProvider);
1375 }
1376 }
1377
1378 UndoLiveUpdateGuard aUndoGuard(
1379 SchResId(STR_ACTION_EDIT_DATA_RANGESreinterpret_cast<char const *>("STR_ACTION_EDIT_DATA_RANGES"
"\004" u8"Edit data ranges")
), m_xUndoManager);
1380
1381 SolarMutexGuard aSolarGuard;
1382 ::chart::DataSourceDialog aDlg(GetChartFrame(), xChartDoc, m_xCC);
1383 if (aDlg.run() == RET_OK)
1384 {
1385 impl_adaptDataSeriesAutoResize();
1386 aUndoGuard.commit();
1387 }
1388}
1389
1390void ChartController::executeDispatch_MoveSeries( bool bForward )
1391{
1392 ControllerLockGuardUNO aCLGuard( getModel() );
1393
1394 //get selected series
1395 OUString aObjectCID(m_aSelection.getSelectedCID());
1396 uno::Reference< XDataSeries > xGivenDataSeries( ObjectIdentifier::getDataSeriesForCID( //yyy todo also legend entries and labels?
1397 aObjectCID, getModel() ) );
1398
1399 UndoGuardWithSelection aUndoGuard(
1400 ActionDescriptionProvider::createDescription(
1401 (bForward ? ActionDescriptionProvider::ActionType::MoveToTop : ActionDescriptionProvider::ActionType::MoveToBottom),
1402 SchResId(STR_OBJECT_DATASERIESreinterpret_cast<char const *>("STR_OBJECT_DATASERIES" "\004"
u8"Data Series")
)),
1403 m_xUndoManager );
1404
1405 bool bChanged = DiagramHelper::moveSeries( ChartModelHelper::findDiagram( getModel() ), xGivenDataSeries, bForward );
1406 if( bChanged )
1407 {
1408 m_aSelection.setSelection( ObjectIdentifier::getMovedSeriesCID( aObjectCID, bForward ) );
1409 aUndoGuard.commit();
1410 }
1411}
1412
1413// ____ XMultiServiceFactory ____
1414uno::Reference< uno::XInterface > SAL_CALL
1415 ChartController::createInstance( const OUString& aServiceSpecifier )
1416{
1417 uno::Reference< uno::XInterface > xResult;
1418
1419 if( aServiceSpecifier == CHART_ACCESSIBLE_TEXT_SERVICE_NAME"com.sun.star.accessibility.AccessibleTextComponent" )
1420 xResult.set( impl_createAccessibleTextContext());
1421 return xResult;
1422}
1423
1424uno::Reference< uno::XInterface > SAL_CALL
1425 ChartController::createInstanceWithArguments(
1426 const OUString& ServiceSpecifier,
1427 const uno::Sequence< uno::Any >& /* Arguments */ )
1428{
1429 // ignore Arguments
1430 return createInstance( ServiceSpecifier );
1431}
1432
1433uno::Sequence< OUString > SAL_CALL
1434 ChartController::getAvailableServiceNames()
1435{
1436 uno::Sequence< OUString > aServiceNames { CHART_ACCESSIBLE_TEXT_SERVICE_NAME"com.sun.star.accessibility.AccessibleTextComponent" };
1437 return aServiceNames;
1438}
1439
1440// ____ XModifyListener ____
1441void SAL_CALL ChartController::modified(
1442 const lang::EventObject& /* aEvent */ )
1443{
1444 // the source can also be a subobject of the ChartModel
1445 // @todo: change the source in ChartModel to always be the model itself ?
1446 //todo? update menu states ?
1447}
1448
1449void ChartController::NotifyUndoActionHdl( std::unique_ptr<SdrUndoAction> pUndoAction )
1450{
1451 ENSURE_OR_RETURN_VOID( pUndoAction, "invalid Undo action" )if( !(pUndoAction) ) { do { if (true && (!(pUndoAction
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "1451" ": "), "%s", "invalid Undo action"); } } while (false
); return; }
;
1452
1453 OUString aObjectCID = m_aSelection.getSelectedCID();
1454 if ( !aObjectCID.isEmpty() )
1455 return;
1456
1457 try
1458 {
1459 const Reference< document::XUndoManagerSupplier > xSuppUndo( getModel(), uno::UNO_QUERY_THROW );
1460 const Reference< document::XUndoManager > xUndoManager( xSuppUndo->getUndoManager(), uno::UNO_SET_THROW );
1461 const Reference< document::XUndoAction > xAction( new impl::ShapeUndoElement( std::move(pUndoAction) ) );
1462 xUndoManager->addUndoAction( xAction );
1463 }
1464 catch( const uno::Exception& )
1465 {
1466 DBG_UNHANDLED_EXCEPTION("chart2")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx"
":" "1466" ": ", "chart2" );
;
1467 }
1468}
1469
1470DrawModelWrapper* ChartController::GetDrawModelWrapper()
1471{
1472 if( !m_pDrawModelWrapper )
1473 {
1474 ExplicitValueProvider* pProvider = comphelper::getUnoTunnelImplementation<ExplicitValueProvider>( m_xChartView );
1475 if( pProvider )
1476 m_pDrawModelWrapper = pProvider->getDrawModelWrapper();
1477 if ( m_pDrawModelWrapper )
1478 {
1479 m_pDrawModelWrapper->getSdrModel().SetNotifyUndoActionHdl(
1480 std::bind(&ChartController::NotifyUndoActionHdl, this, std::placeholders::_1) );
1481 }
1482 }
1483 return m_pDrawModelWrapper.get();
1484}
1485
1486DrawViewWrapper* ChartController::GetDrawViewWrapper()
1487{
1488 if ( !m_pDrawViewWrapper )
1489 {
1490 impl_createDrawViewController();
1491 }
1492 return m_pDrawViewWrapper.get();
1493}
1494
1495
1496VclPtr<ChartWindow> ChartController::GetChartWindow() const
1497{
1498 // clients getting the naked VCL Window from UNO should always have the
1499 // solar mutex (and keep it over the lifetime of this ptr), as VCL might
1500 // might deinit otherwise
1501 DBG_TESTSOLARMUTEX()do { DbgTestSolarMutex(); } while(false);
2
Loop condition is false. Exiting loop
1502 if(!m_xViewWindow.is())
3
Taking false branch
1503 return nullptr;
1504 return dynamic_cast<ChartWindow*>(VCLUnoHelper::GetWindow(m_xViewWindow).get());
4
Calling constructor for 'VclPtr<chart::ChartWindow>'
9
Returning from constructor for 'VclPtr<chart::ChartWindow>'
10
Calling implicit destructor for 'VclPtr<vcl::Window>'
11
Calling '~Reference'
18
Returning from '~Reference'
19
Returning from destructor for 'VclPtr<vcl::Window>'
1505}
1506
1507weld::Window* ChartController::GetChartFrame()
1508{
1509 // clients getting the naked VCL Window from UNO should always have the
1510 // solar mutex (and keep it over the lifetime of this ptr), as VCL might
1511 // might deinit otherwise
1512 DBG_TESTSOLARMUTEX()do { DbgTestSolarMutex(); } while(false);
1513 return Application::GetFrameWeld(m_xViewWindow);
1514}
1515
1516bool ChartController::isAdditionalShapeSelected() const
1517{
1518 return m_aSelection.isAdditionalShapeSelected();
1519}
1520
1521void ChartController::SetAndApplySelection(const Reference<drawing::XShape>& rxShape)
1522{
1523 if(rxShape.is())
1524 {
1525 m_aSelection.setSelection(rxShape);
1526 m_aSelection.applySelection(GetDrawViewWrapper());
1527 }
1528}
1529
1530
1531
1532uno::Reference< XAccessible > ChartController::CreateAccessible()
1533{
1534 uno::Reference< XAccessible > xResult = new AccessibleChartView( GetDrawViewWrapper() );
1535 impl_initializeAccessible( uno::Reference< lang::XInitialization >( xResult, uno::UNO_QUERY ) );
1536 return xResult;
1537}
1538
1539void ChartController::impl_invalidateAccessible()
1540{
1541 SolarMutexGuard aGuard;
1542 auto pChartWindow(GetChartWindow());
1543 if( pChartWindow )
1544 {
1545 Reference< lang::XInitialization > xInit( pChartWindow->GetAccessible(false), uno::UNO_QUERY );
1546 if(xInit.is())
1547 {
1548 uno::Sequence< uno::Any > aArguments(3);//empty arguments -> invalid accessible
1549 xInit->initialize(aArguments);
1550 }
1551 }
1552}
1553void ChartController::impl_initializeAccessible()
1554{
1555 SolarMutexGuard aGuard;
1556 auto pChartWindow(GetChartWindow());
1557 if( pChartWindow )
1558 this->impl_initializeAccessible( Reference< lang::XInitialization >( pChartWindow->GetAccessible(false), uno::UNO_QUERY ) );
1559}
1560void ChartController::impl_initializeAccessible( const uno::Reference< lang::XInitialization >& xInit )
1561{
1562 if(!xInit.is())
1563 return;
1564
1565 uno::Sequence< uno::Any > aArguments(5);
1566 aArguments[0] <<= uno::Reference<view::XSelectionSupplier>(this);
1567 aArguments[1] <<= getModel();
1568 aArguments[2] <<= m_xChartView;
1569 uno::Reference< XAccessible > xParent;
1570 {
1571 SolarMutexGuard aGuard;
1572 auto pChartWindow(GetChartWindow());
1573 if( pChartWindow )
1574 {
1575 vcl::Window* pParentWin( pChartWindow->GetAccessibleParentWindow());
1576 if( pParentWin )
1577 xParent.set( pParentWin->GetAccessible());
1578 }
1579 }
1580 aArguments[3] <<= xParent;
1581 aArguments[4] <<= m_xViewWindow;
1582
1583 xInit->initialize(aArguments);
1584}
1585
1586const o3tl::sorted_vector< OUString >& ChartController::impl_getAvailableCommands()
1587{
1588 static const o3tl::sorted_vector< OUString > s_AvailableCommands {
1589 // commands for container forward
1590 "AddDirect", "NewDoc", "Open",
1591 "Save", "SaveAs", "SendMail",
1592 "EditDoc", "ExportDirectToPDF", "PrintDefault",
1593
1594 // own commands
1595 "Cut", "Copy", "Paste",
1596 "DataRanges", "DiagramData",
1597 // insert objects
1598 "InsertMenuTitles", "InsertTitles",
1599 "InsertMenuLegend", "InsertLegend", "DeleteLegend",
1600 "InsertMenuDataLabels",
1601 "InsertMenuAxes", "InsertRemoveAxes", "InsertMenuGrids",
1602 "InsertSymbol",
1603 "InsertTrendlineEquation", "InsertTrendlineEquationAndR2",
1604 "InsertR2Value", "DeleteR2Value",
1605 "InsertMenuTrendlines", "InsertTrendline",
1606 "InsertMenuMeanValues", "InsertMeanValue",
1607 "InsertMenuXErrorBars", "InsertXErrorBars",
1608 "InsertMenuYErrorBars", "InsertYErrorBars",
1609 "InsertDataLabels", "InsertDataLabel",
1610 "DeleteTrendline", "DeleteMeanValue", "DeleteTrendlineEquation",
1611 "DeleteXErrorBars", "DeleteYErrorBars",
1612 "DeleteDataLabels", "DeleteDataLabel",
1613 //format objects
1614 "FormatSelection", "TransformDialog",
1615 "DiagramType", "View3D",
1616 "Forward", "Backward",
1617 "MainTitle", "SubTitle",
1618 "XTitle", "YTitle", "ZTitle",
1619 "SecondaryXTitle", "SecondaryYTitle",
1620 "AllTitles", "Legend",
1621 "DiagramAxisX", "DiagramAxisY", "DiagramAxisZ",
1622 "DiagramAxisA", "DiagramAxisB", "DiagramAxisAll",
1623 "DiagramGridXMain", "DiagramGridYMain", "DiagramGridZMain",
1624 "DiagramGridXHelp", "DiagramGridYHelp", "DiagramGridZHelp",
1625 "DiagramGridAll",
1626 "DiagramWall", "DiagramFloor", "DiagramArea",
1627
1628 //context menu - format objects entries
1629 "FormatWall", "FormatFloor", "FormatChartArea",
1630 "FormatLegend",
1631
1632 "FormatAxis", "FormatTitle",
1633 "FormatDataSeries", "FormatDataPoint",
1634 "ResetAllDataPoints", "ResetDataPoint",
1635 "FormatDataLabels", "FormatDataLabel",
1636 "FormatMeanValue", "FormatTrendline", "FormatTrendlineEquation",
1637 "FormatXErrorBars", "FormatYErrorBars",
1638 "FormatStockLoss", "FormatStockGain",
1639
1640 "FormatMajorGrid", "InsertMajorGrid", "DeleteMajorGrid",
1641 "FormatMinorGrid", "InsertMinorGrid", "DeleteMinorGrid",
1642 "InsertAxis", "DeleteAxis", "InsertAxisTitle",
1643
1644 // toolbar commands
1645 "ToggleGridHorizontal", "ToggleGridVertical", "ToggleLegend", "ScaleText",
1646 "NewArrangement", "Update",
1647 "DefaultColors", "BarWidth", "NumberOfLines",
1648 "ArrangeRow",
1649 "StatusBarVisible",
1650 "ChartElementSelector"};
1651 return s_AvailableCommands;
1652}
1653
1654ViewElementListProvider ChartController::getViewElementListProvider()
1655{
1656 return ViewElementListProvider(m_pDrawModelWrapper.get());
1657}
1658
1659} //namespace chart
1660
1661extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface *
1662com_sun_star_comp_chart2_ChartController_get_implementation(css::uno::XComponentContext *context,
1663 css::uno::Sequence<css::uno::Any> const &)
1664{
1665 return cppu::acquire(new chart::ChartController(context));
1666}
1667
1668/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.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
20#ifndef INCLUDED_VCL_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
5
Calling constructor for 'Reference<chart::ChartWindow>'
8
Returning from constructor for 'Reference<chart::ChartWindow>'
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
205 if (aTmp.get()) {
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/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
20#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
6
Assuming field 'm_pBody' is non-null
7
Taking true branch
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody
11.1
Field 'm_pBody' is non-null
26.1
Field 'm_pBody' is non-null
11.1
Field 'm_pBody' is non-null
26.1
Field 'm_pBody' is non-null
11.1
Field 'm_pBody' is non-null
26.1
Field 'm_pBody' is non-null
11.1
Field 'm_pBody' is non-null
26.1
Field 'm_pBody' is non-null
)
12
Taking true branch
27
Taking true branch
113 m_pBody->release();
13
Calling 'VclReferenceBase::release'
17
Returning; memory was released
28
Use of memory after it is freed
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody)
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.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_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
14
Assuming the condition is true
15
Taking true branch
40 delete this;
16
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif