LibreOffice Module chart2 (master) 1
AccessibleChartView.cxx
Go to the documentation of this file.
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
22#include <ObjectHierarchy.hxx>
23#include <ObjectIdentifier.hxx>
24#include <ResId.hxx>
25#include <strings.hrc>
27#include <ChartModel.hxx>
28#include <ChartView.hxx>
29
30#include <com/sun/star/accessibility/AccessibleStateType.hpp>
31#include <com/sun/star/accessibility/AccessibleRole.hpp>
32#include <com/sun/star/view/XSelectionSupplier.hpp>
33
35
36#include <rtl/ustring.hxx>
37#include <vcl/window.hxx>
39#include <vcl/svapp.hxx>
40#include <osl/mutex.hxx>
41
42using namespace ::com::sun::star;
43using namespace ::com::sun::star::accessibility;
44
45using ::com::sun::star::uno::Sequence;
46using ::com::sun::star::uno::Reference;
47using ::com::sun::star::uno::WeakReference;
48using ::com::sun::star::uno::Any;
49using osl::MutexGuard;
50
51namespace chart
52{
53
56 AccessibleElementInfo(), // empty for now
57 true, // has children
58 true // always transparent
59 ),
60 m_pSdrView( pView )
61{
62 AddState( AccessibleStateType::OPAQUE );
63}
64
66{
67}
68
70{
72 if( ! xWindow.is())
73 return awt::Rectangle();
74
75 awt::Rectangle aBBox( xWindow->getPosSize() );
76
78 if( pWindow )
79 {
80 SolarMutexGuard aSolarGuard;
81 Point aVCLPoint( pWindow->OutputToAbsoluteScreenPixel( Point( 0, 0 ) ));
82 aBBox.X = aVCLPoint.getX();
83 aBBox.Y = aVCLPoint.getY();
84 }
85
86 return aBBox;
87}
88
90{
91 awt::Point aParentPosition;
92
93 awt::Rectangle aBBox( GetWindowPosSize() );
94 aParentPosition.X = aBBox.X;
95 aParentPosition.Y = aBBox.Y;
96
97 return aParentPosition;
98}
99
100// ________ XAccessibleContext ________
102{
103 return SchResId(STR_OBJECT_DIAGRAM);
104}
105
107{
108 return getAccessibleName();
109}
110
112{
114}
115
117{
118 // the document is always the only child of the window
119 return 0;
120}
121
123{
124 return AccessibleRole::DOCUMENT;
125}
126
127// ________ XAccessibleComponent ________
128awt::Rectangle SAL_CALL AccessibleChartView::getBounds()
129{
130 awt::Rectangle aResult( GetWindowPosSize());
132 if( xParent.is())
133 {
134 Reference< XAccessibleComponent > xContext( xParent->getAccessibleContext(), uno::UNO_QUERY );
135 if( xContext.is())
136 {
137 awt::Point aParentPosition = xContext->getLocationOnScreen();
138 aResult.X -= aParentPosition.X;
139 aResult.Y -= aParentPosition.Y;
140 }
141 }
142 return aResult;
143}
144
146{
147 awt::Rectangle aBounds( getBounds());
148 awt::Point aResult;
150 if( xParent.is())
151 {
153 xParent->getAccessibleContext(), uno::UNO_QUERY );
154 aResult = xAccComp->getLocationOnScreen();
155 aResult.X += aBounds.X;
156 aResult.Y += aBounds.Y;
157 }
158 return aResult;
159}
160
161// lang::XInitialization
162
163void SAL_CALL AccessibleChartView::initialize( const Sequence< Any >& rArguments )
164{
165 //0: view::XSelectionSupplier offers notifications for selection changes and access to the selection itself
166 //1: frame::XModel representing the chart model - offers access to object data
167 //2: lang::XInterface representing the normal chart view - offers access to some extra object data
168
169 //all arguments are only valid until next initialization
170 bool bChanged = false;
171 bool bOldInvalid = false;
172 bool bNewInvalid = false;
173
174 Reference< view::XSelectionSupplier > xSelectionSupplier;
179 {
180 MutexGuard aGuard( m_aMutex);
181 xSelectionSupplier.set( m_xSelectionSupplier );
182 xChartModel = m_xChartModel;
183 xChartView = m_xChartView;
184 xParent.set( m_xParent );
185 xWindow.set( m_xWindow );
186 }
187
188 if( !xSelectionSupplier.is() || !xChartModel.is() || !xChartView.is() )
189 {
190 bOldInvalid = true;
191 }
192
193 if( rArguments.getLength() > 1 )
194 {
195 Reference< frame::XModel > xNewChartModel;
196 rArguments[1] >>= xNewChartModel;
197 assert(!xNewChartModel || dynamic_cast<::chart::ChartModel*>(xNewChartModel.get()));
198 ::chart::ChartModel* pNewChartModel = dynamic_cast<::chart::ChartModel*>(xNewChartModel.get());
199 if( pNewChartModel != xChartModel.get() )
200 {
201 xChartModel = pNewChartModel;
202 bChanged = true;
203 }
204 }
205 else if( xChartModel.is() )
206 {
207 bChanged = true;
208 xChartModel = nullptr;
209 }
210
211 if( rArguments.getLength() > 2 )
212 {
214 rArguments[2] >>= xTmp;
215 rtl::Reference<::chart::ChartView> xNewChartView = dynamic_cast<::chart::ChartView*>(xTmp.get());
216 assert(bool(xTmp)==bool(xNewChartView) && "we only support ChartView");
217 if( xNewChartView != xChartView )
218 {
219 xChartView = xNewChartView;
220 bChanged = true;
221 }
222 }
223 else if( xChartView.is() )
224 {
225 bChanged = true;
226 xChartView = nullptr;
227 }
228
229 if( rArguments.getLength() > 3 )
230 {
231 Reference< XAccessible > xNewParent;
232 rArguments[3] >>= xNewParent;
233 if( xNewParent != xParent )
234 {
235 xParent = xNewParent;
236 bChanged = true;
237 }
238 }
239
240 if( rArguments.getLength() > 4 )
241 {
242 Reference< awt::XWindow > xNewWindow;
243 rArguments[4] >>= xNewWindow;
244 if( xNewWindow != xWindow )
245 {
246 xWindow.set( xNewWindow );
247 bChanged = true;
248 }
249 }
250
251 if( rArguments.hasElements() && xChartModel.is() && xChartView.is() )
252 {
253 Reference< view::XSelectionSupplier > xNewSelectionSupplier;
254 rArguments[0] >>= xNewSelectionSupplier;
255 if(xSelectionSupplier!=xNewSelectionSupplier)
256 {
257 bChanged = true;
258 if(xSelectionSupplier.is())
259 xSelectionSupplier->removeSelectionChangeListener(this);
260 if(xNewSelectionSupplier.is())
261 xNewSelectionSupplier->addSelectionChangeListener(this);
262 xSelectionSupplier = xNewSelectionSupplier;
263 }
264 }
265 else if( xSelectionSupplier.is() )
266 {
267 bChanged = true;
268 xSelectionSupplier->removeSelectionChangeListener(this);
269 xSelectionSupplier = nullptr;
270 }
271
272 if( !xSelectionSupplier.is() || !xChartModel.is() || !xChartView.is() )
273 {
274 if(xSelectionSupplier.is())
275 xSelectionSupplier->removeSelectionChangeListener(this);
276 xSelectionSupplier = nullptr;
277 xChartModel.clear();
278 xChartView.clear();
279 xParent.clear();
280 xWindow.clear();
281
282 bNewInvalid = true;
283 }
284
285 {
286 MutexGuard aGuard( m_aMutex);
288 m_xChartModel = xChartModel.get();
289 m_xChartView = xChartView.get();
292 }
293
294 if( bOldInvalid && bNewInvalid )
295 bChanged = false;
296
297 if( !bChanged )
298 return;
299
300 {
301 //before notification we prepare for creation of new context
302 //the old context will be deleted after notification than
303 MutexGuard aGuard( m_aMutex);
304 if( xChartModel.is())
306 std::make_shared<ObjectHierarchy>( xChartModel, m_xChartView.get().get() );
307 else
308 m_spObjectHierarchy.reset();
309 }
310
311 {
312 AccessibleElementInfo aAccInfo;
313 aAccInfo.m_aOID = ObjectIdentifier("ROOT");
316 aAccInfo.m_xView = m_xChartView;
317 aAccInfo.m_xWindow = m_xWindow;
318 aAccInfo.m_pParent = nullptr;
320 aAccInfo.m_pSdrView = m_pSdrView;
322 m_pViewForwarder.reset( new AccessibleViewForwarder( this, pWindow ) );
323 aAccInfo.m_pViewForwarder = m_pViewForwarder.get();
324 // broadcasts an INVALIDATE_ALL_CHILDREN event globally
325 SetInfo( aAccInfo );
326 }
327}
328
329// view::XSelectionChangeListener
330
331void SAL_CALL AccessibleChartView::selectionChanged( const lang::EventObject& /*rEvent*/ )
332{
333 Reference< view::XSelectionSupplier > xSelectionSupplier;
334 {
335 MutexGuard aGuard( m_aMutex);
336 xSelectionSupplier.set(m_xSelectionSupplier);
337 }
338
339 if( !xSelectionSupplier.is() )
340 return;
341
342 ObjectIdentifier aSelectedOID( xSelectionSupplier->getSelection() );
344 {
345 NotifyEvent( EventType::LOST_SELECTION, m_aCurrentSelectionOID );
346 }
347 if( aSelectedOID.isValid() )
348 {
349 NotifyEvent( EventType::GOT_SELECTION, aSelectedOID );
350 }
351 m_aCurrentSelectionOID = aSelectedOID;
352}
353
354// XEventListener
355void SAL_CALL AccessibleChartView::disposing( const lang::EventObject& /*Source*/ )
356{
357}
358
359} //namespace chart
360
361/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr tools::Long getX() const
constexpr tools::Long getY() const
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
virtual void SAL_CALL selectionChanged(const css::lang::EventObject &aEvent) override
std::shared_ptr< ObjectHierarchy > m_spObjectHierarchy
virtual OUString SAL_CALL getAccessibleName() override
virtual sal_Int16 SAL_CALL getAccessibleRole() override
virtual OUString SAL_CALL getAccessibleDescription() override
virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override
unotools::WeakReference< ChartView > m_xChartView
std::unique_ptr<::accessibility::IAccessibleViewForwarder > m_pViewForwarder
css::uno::WeakReference< css::view::XSelectionSupplier > m_xSelectionSupplier
css::uno::WeakReference< css::accessibility::XAccessible > m_xParent
virtual css::awt::Point SAL_CALL getLocationOnScreen() override
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &aArguments) override
css::awt::Rectangle GetWindowPosSize() const
virtual css::awt::Rectangle SAL_CALL getBounds() override
virtual void SAL_CALL disposing() override
virtual ~AccessibleChartView() override
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent() override
virtual css::awt::Point GetUpperLeftOnScreen() const override
unotools::WeakReference<::chart::ChartModel > m_xChartModel
AccessibleUniqueId m_aCurrentSelectionOID
css::uno::WeakReference< css::awt::XWindow > m_xWindow
The ChartView is responsible to manage the generation of Drawing Objects for visualization on a given...
Definition: ChartView.hxx:98
std::mutex m_aMutex
::cppu::ImplInheritanceHelper< ::chart::AccessibleBase, css::lang::XInitialization, css::view::XSelectionChangeListener > AccessibleChartView_Base
OUString OOO_DLLPUBLIC_CHARTTOOLS SchResId(TranslateId aId)
Definition: ResId.cxx:24
css::uno::WeakReference< css::awt::XWindow > m_xWindow
std::shared_ptr< ObjectHierarchy > m_spObjectHierarchy
css::uno::WeakReference< css::view::XSelectionSupplier > m_xSelectionSupplier
::accessibility::IAccessibleViewForwarder * m_pViewForwarder
unotools::WeakReference< ::chart::ChartModel > m_xChartDocument
unotools::WeakReference< ::chart::ChartView > m_xView