1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_chartcontroller.hxx" 26 27 #include "AccessibleChartView.hxx" 28 #include "chartview/ExplicitValueProvider.hxx" 29 #include "servicenames.hxx" 30 #include "macros.hxx" 31 #include "ObjectHierarchy.hxx" 32 #include "ObjectIdentifier.hxx" 33 #include "ResId.hxx" 34 #include "Strings.hrc" 35 #include "AccessibleViewForwarder.hxx" 36 37 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 38 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 39 #include <com/sun/star/accessibility/AccessibleRole.hpp> 40 41 #include <tools/string.hxx> 42 #include <vcl/window.hxx> 43 #include <toolkit/helper/vclunohelper.hxx> 44 // for SolarMutex 45 #include <vcl/svapp.hxx> 46 47 // header for typedef MutexGuard 48 #include <osl/mutex.hxx> 49 50 using namespace ::com::sun::star; 51 using namespace ::com::sun::star::accessibility; 52 53 using ::com::sun::star::uno::Sequence; 54 using ::com::sun::star::uno::Reference; 55 using ::com::sun::star::uno::WeakReference; 56 using ::com::sun::star::uno::Any; 57 using ::rtl::OUString; 58 using osl::MutexGuard; 59 60 //............................................................................. 61 namespace chart 62 { 63 //............................................................................. 64 65 AccessibleChartView::AccessibleChartView( 66 const Reference< uno::XComponentContext >& xContext, SdrView* pView ) : 67 impl::AccessibleChartView_Base( 68 AccessibleElementInfo(), // empty for now 69 true, // has children 70 true // always transparent 71 ), 72 m_xContext( xContext ), 73 m_pSdrView( pView ), 74 m_pViewForwarder( NULL ) 75 { 76 AddState( AccessibleStateType::OPAQUE ); 77 } 78 79 AccessibleChartView::~AccessibleChartView() 80 { 81 delete m_pViewForwarder; 82 } 83 84 85 awt::Rectangle AccessibleChartView::GetWindowPosSize() const 86 { 87 Reference< awt::XWindow > xWindow( GetInfo().m_xWindow ); 88 if( ! xWindow.is()) 89 return awt::Rectangle(); 90 91 // this should do, but it doesn't => HACK 92 // return xWindow->getPosSize(); 93 94 awt::Rectangle aBBox( xWindow->getPosSize() ); 95 96 Window* pWindow( VCLUnoHelper::GetWindow( GetInfo().m_xWindow )); 97 if( pWindow ) 98 { 99 // /-- solar 100 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 101 Point aVCLPoint( pWindow->OutputToAbsoluteScreenPixel( Point( 0, 0 ) )); 102 aBBox.X = aVCLPoint.getX(); 103 aBBox.Y = aVCLPoint.getY(); 104 // \-- solar 105 } 106 107 return aBBox; 108 } 109 110 awt::Point AccessibleChartView::GetUpperLeftOnScreen() const 111 { 112 awt::Point aParentPosition; 113 114 awt::Rectangle aBBox( GetWindowPosSize() ); 115 aParentPosition.X = aBBox.X; 116 aParentPosition.Y = aBBox.Y; 117 118 return aParentPosition; 119 } 120 121 // ________ XAccessibleContext ________ 122 OUString SAL_CALL AccessibleChartView::getAccessibleName() 123 { 124 return OUString( String( SchResId( STR_OBJECT_DIAGRAM ))); 125 } 126 127 OUString SAL_CALL AccessibleChartView::getAccessibleDescription() 128 { 129 return getAccessibleName(); 130 } 131 132 Reference< XAccessible > SAL_CALL AccessibleChartView::getAccessibleParent() 133 { 134 return Reference< XAccessible >( m_xParent ); 135 } 136 137 sal_Int32 SAL_CALL AccessibleChartView::getAccessibleIndexInParent() 138 { 139 // the document is always the only child of the window 140 return 0; 141 } 142 143 sal_Int16 SAL_CALL AccessibleChartView::getAccessibleRole() 144 { 145 return AccessibleRole::DOCUMENT; 146 } 147 148 // ________ XAccessibleComponent ________ 149 awt::Rectangle SAL_CALL AccessibleChartView::getBounds() 150 { 151 awt::Rectangle aResult( GetWindowPosSize()); 152 Reference< XAccessible > xParent( m_xParent ); 153 if( xParent.is()) 154 { 155 Reference< XAccessibleComponent > xContext( xParent->getAccessibleContext(), uno::UNO_QUERY ); 156 if( xContext.is()) 157 { 158 awt::Point aParentPosition = xContext->getLocationOnScreen(); 159 aResult.X -= aParentPosition.X; 160 aResult.Y -= aParentPosition.Y; 161 } 162 } 163 return aResult; 164 } 165 166 awt::Point SAL_CALL AccessibleChartView::getLocationOnScreen() 167 { 168 awt::Rectangle aBounds( getBounds()); 169 awt::Point aResult; 170 Reference< XAccessible > xParent( m_xParent ); 171 if( xParent.is()) 172 { 173 Reference< XAccessibleComponent > xAccComp( 174 xParent->getAccessibleContext(), uno::UNO_QUERY ); 175 aResult = xAccComp->getLocationOnScreen(); 176 aResult.X += aBounds.X; 177 aResult.Y += aBounds.Y; 178 } 179 return aResult; 180 } 181 182 //----------------------------------------------------------------- 183 // lang::XInitialization 184 //----------------------------------------------------------------- 185 186 void SAL_CALL AccessibleChartView::initialize( const Sequence< Any >& rArguments ) 187 { 188 //0: view::XSelectionSupplier offers notifications for selection changes and access to the selection itself 189 //1: frame::XModel representing the chart model - offers access to object data 190 //2: lang::XInterface representing the normal chart view - offers access to some extra object data 191 192 //all arguments are only valid until next initialization 193 bool bChanged = false; 194 bool bOldInvalid = false; 195 bool bNewInvalid = false; 196 197 Reference< view::XSelectionSupplier > xSelectionSupplier; 198 Reference< frame::XModel > xChartModel; 199 Reference< uno::XInterface > xChartView; 200 Reference< XAccessible > xParent; 201 Reference< awt::XWindow > xWindow; 202 { 203 MutexGuard aGuard( GetMutex()); 204 xSelectionSupplier.set( m_xSelectionSupplier ); 205 xChartModel.set( m_xChartModel ); 206 xChartView.set( m_xChartView ); 207 xParent.set( m_xParent ); 208 xWindow.set( m_xWindow ); 209 } 210 211 if( !xSelectionSupplier.is() || !xChartModel.is() || !xChartView.is() ) 212 { 213 bOldInvalid = true; 214 } 215 216 if( rArguments.getLength() > 1 ) 217 { 218 Reference< frame::XModel > xNewChartModel; 219 rArguments[1] >>= xNewChartModel; 220 if( xNewChartModel != xChartModel ) 221 { 222 xChartModel = xNewChartModel; 223 bChanged = true; 224 } 225 } 226 else if( xChartModel.is() ) 227 { 228 bChanged = true; 229 xChartModel = 0; 230 } 231 232 if( rArguments.getLength() > 2 ) 233 { 234 Reference< uno::XInterface > xNewChartView; 235 rArguments[2] >>= xNewChartView; 236 if( xNewChartView != xChartView ) 237 { 238 xChartView = xNewChartView; 239 bChanged = true; 240 } 241 } 242 else if( xChartView.is() ) 243 { 244 bChanged = true; 245 xChartView = 0; 246 } 247 248 if( rArguments.getLength() > 3 ) 249 { 250 Reference< XAccessible > xNewParent; 251 rArguments[3] >>= xNewParent; 252 if( xNewParent != xParent ) 253 { 254 xParent = xNewParent; 255 bChanged = true; 256 } 257 } 258 259 if( rArguments.getLength() > 4 ) 260 { 261 Reference< awt::XWindow > xNewWindow; 262 rArguments[4] >>= xNewWindow; 263 if( xNewWindow != xWindow ) 264 { 265 xWindow.set( xNewWindow ); 266 bChanged = true; 267 } 268 } 269 270 if( rArguments.getLength() > 0 && xChartModel.is() && xChartView.is() ) 271 { 272 Reference< view::XSelectionSupplier > xNewSelectionSupplier; 273 rArguments[0] >>= xNewSelectionSupplier; 274 if(xSelectionSupplier!=xNewSelectionSupplier) 275 { 276 bChanged = true; 277 if(xSelectionSupplier.is()) 278 xSelectionSupplier->removeSelectionChangeListener(this); 279 if(xNewSelectionSupplier.is()) 280 xNewSelectionSupplier->addSelectionChangeListener(this); 281 xSelectionSupplier = xNewSelectionSupplier; 282 } 283 } 284 else if( xSelectionSupplier.is() ) 285 { 286 bChanged = true; 287 xSelectionSupplier->removeSelectionChangeListener(this); 288 xSelectionSupplier = 0; 289 } 290 291 if( !xSelectionSupplier.is() || !xChartModel.is() || !xChartView.is() ) 292 { 293 if(xSelectionSupplier.is()) 294 xSelectionSupplier->removeSelectionChangeListener(this); 295 xSelectionSupplier = 0; 296 xChartModel.clear(); 297 xChartView.clear(); 298 xParent.clear(); 299 xWindow.clear(); 300 301 bNewInvalid = true; 302 } 303 304 { 305 MutexGuard aGuard( GetMutex()); 306 m_xSelectionSupplier = WeakReference< view::XSelectionSupplier >(xSelectionSupplier); 307 m_xChartModel = WeakReference< frame::XModel >(xChartModel); 308 m_xChartView = WeakReference< uno::XInterface >(xChartView); 309 m_xParent = WeakReference< XAccessible >(xParent); 310 m_xWindow = WeakReference< awt::XWindow >(xWindow); 311 } 312 313 if( bOldInvalid && bNewInvalid ) 314 bChanged = false; 315 316 if( bChanged ) 317 { 318 { 319 //before notification we prepare for creation of new context 320 //the old context will be deleted after notification than 321 MutexGuard aGuard( GetMutex()); 322 Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY ); 323 if( xChartDoc.is()) 324 m_spObjectHierarchy.reset( new ObjectHierarchy( xChartDoc, getExplicitValueProvider() )); 325 else 326 m_spObjectHierarchy.reset(); 327 } 328 329 { 330 AccessibleElementInfo aAccInfo; 331 aAccInfo.m_aOID = ObjectIdentifier( C2U( "ROOT" ) ); 332 aAccInfo.m_xChartDocument = uno::WeakReference< chart2::XChartDocument >( 333 uno::Reference< chart2::XChartDocument >( m_xChartModel.get(), uno::UNO_QUERY )); 334 aAccInfo.m_xSelectionSupplier = m_xSelectionSupplier; 335 aAccInfo.m_xView = m_xChartView; 336 aAccInfo.m_xWindow = m_xWindow; 337 aAccInfo.m_pParent = 0; 338 aAccInfo.m_spObjectHierarchy = m_spObjectHierarchy; 339 aAccInfo.m_pSdrView = m_pSdrView; 340 Window* pWindow = VCLUnoHelper::GetWindow( m_xWindow ); 341 if ( m_pViewForwarder ) 342 { 343 delete m_pViewForwarder; 344 } 345 m_pViewForwarder = new AccessibleViewForwarder( this, pWindow ); 346 aAccInfo.m_pViewForwarder = m_pViewForwarder; 347 // broadcasts an INVALIDATE_ALL_CHILDREN event globally 348 SetInfo( aAccInfo ); 349 } 350 } 351 } 352 353 ExplicitValueProvider* AccessibleChartView::getExplicitValueProvider() 354 { 355 return ExplicitValueProvider::getExplicitValueProvider(m_xChartView); 356 } 357 358 //------------------------------------------------------------------------- 359 // view::XSelectionChangeListener 360 //------------------------------------------------------------------------- 361 362 void SAL_CALL AccessibleChartView::selectionChanged( const lang::EventObject& /*rEvent*/ ) 363 { 364 Reference< view::XSelectionSupplier > xSelectionSupplier; 365 { 366 MutexGuard aGuard( GetMutex()); 367 xSelectionSupplier = Reference< view::XSelectionSupplier >(m_xSelectionSupplier); 368 } 369 370 if( xSelectionSupplier.is() ) 371 { 372 ObjectIdentifier aSelectedOID( xSelectionSupplier->getSelection() ); 373 if ( m_aCurrentSelectionOID.isValid() ) 374 { 375 NotifyEvent( LOST_SELECTION, m_aCurrentSelectionOID ); 376 } 377 if( aSelectedOID.isValid() ) 378 { 379 NotifyEvent( GOT_SELECTION, aSelectedOID ); 380 } 381 m_aCurrentSelectionOID = aSelectedOID; 382 } 383 } 384 385 //------------------------------------------------------------------------- 386 // lang::XComponent::dispose() 387 //------------------------------------------------------------------------- 388 void SAL_CALL AccessibleChartView::disposing() 389 { 390 AccessibleBase::disposing(); 391 } 392 393 //------------------------------------------------------------------------- 394 // XEventListener 395 //------------------------------------------------------------------------- 396 void SAL_CALL AccessibleChartView::disposing( const lang::EventObject& /*Source*/ ) 397 { 398 } 399 400 //............................................................................. 401 } //namespace chart 402 //............................................................................. 403