1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sd.hxx" 30 31 #include "AccessibleSlideSorterObject.hxx" 32 33 #include "SlideSorter.hxx" 34 #include "controller/SlideSorterController.hxx" 35 #include "controller/SlsPageSelector.hxx" 36 #include "controller/SlsFocusManager.hxx" 37 #include "model/SlideSorterModel.hxx" 38 #include "model/SlsPageDescriptor.hxx" 39 #include "view/SlideSorterView.hxx" 40 #include "view/SlsLayouter.hxx" 41 #include "view/SlsPageObjectLayouter.hxx" 42 #include <com/sun/star/accessibility/AccessibleRole.hpp> 43 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 44 #include <comphelper/accessibleeventnotifier.hxx> 45 #include <unotools/accessiblestatesethelper.hxx> 46 47 #include "sdpage.hxx" 48 #include "sdresid.hxx" 49 #include <vcl/svapp.hxx> 50 51 #include "glob.hrc" 52 53 using ::rtl::OUString; 54 using namespace ::com::sun::star; 55 using namespace ::com::sun::star::uno; 56 using namespace ::com::sun::star::accessibility; 57 58 59 namespace accessibility { 60 61 62 AccessibleSlideSorterObject::AccessibleSlideSorterObject( 63 const Reference<XAccessible>& rxParent, 64 ::sd::slidesorter::SlideSorter& rSlideSorter, 65 sal_uInt16 nPageNumber) 66 : AccessibleSlideSorterObjectBase(::sd::MutexOwner::maMutex), 67 mxParent(rxParent), 68 mnPageNumber(nPageNumber), 69 mrSlideSorter(rSlideSorter), 70 mnClientId(0) 71 { 72 } 73 74 75 76 77 AccessibleSlideSorterObject::~AccessibleSlideSorterObject (void) 78 { 79 if ( ! IsDisposed()) 80 dispose(); 81 } 82 83 84 85 86 sal_uInt16 AccessibleSlideSorterObject::GetPageNumber (void) const 87 { 88 return mnPageNumber; 89 } 90 91 92 93 94 void AccessibleSlideSorterObject::FireAccessibleEvent ( 95 short nEventId, 96 const uno::Any& rOldValue, 97 const uno::Any& rNewValue) 98 { 99 if (mnClientId != 0) 100 { 101 AccessibleEventObject aEventObject; 102 103 aEventObject.Source = Reference<XWeak>(this); 104 aEventObject.EventId = nEventId; 105 aEventObject.NewValue = rNewValue; 106 aEventObject.OldValue = rOldValue; 107 108 comphelper::AccessibleEventNotifier::addEvent(mnClientId, aEventObject); 109 } 110 } 111 112 113 114 115 void SAL_CALL AccessibleSlideSorterObject::disposing (void) 116 { 117 const vos::OGuard aSolarGuard (Application::GetSolarMutex()); 118 119 // Send a disposing to all listeners. 120 if (mnClientId != 0) 121 { 122 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing(mnClientId, *this); 123 mnClientId = 0; 124 } 125 } 126 127 128 129 //===== XAccessible =========================================================== 130 131 Reference<XAccessibleContext> SAL_CALL 132 AccessibleSlideSorterObject::getAccessibleContext (void) 133 throw (uno::RuntimeException) 134 { 135 ThrowIfDisposed(); 136 return this; 137 } 138 139 140 141 //===== XAccessibleContext ==================================================== 142 143 sal_Int32 SAL_CALL AccessibleSlideSorterObject::getAccessibleChildCount (void) 144 throw (uno::RuntimeException) 145 { 146 ThrowIfDisposed(); 147 return 0; 148 } 149 150 151 152 153 Reference<XAccessible> SAL_CALL AccessibleSlideSorterObject::getAccessibleChild (sal_Int32 ) 154 throw (lang::IndexOutOfBoundsException, RuntimeException) 155 { 156 ThrowIfDisposed(); 157 throw lang::IndexOutOfBoundsException(); 158 } 159 160 161 162 163 Reference<XAccessible> SAL_CALL AccessibleSlideSorterObject::getAccessibleParent (void) 164 throw (uno::RuntimeException) 165 { 166 ThrowIfDisposed(); 167 return mxParent; 168 } 169 170 171 172 173 sal_Int32 SAL_CALL AccessibleSlideSorterObject::getAccessibleIndexInParent() 174 throw (uno::RuntimeException) 175 { 176 ThrowIfDisposed(); 177 const vos::OGuard aSolarGuard (Application::GetSolarMutex()); 178 sal_Int32 nIndexInParent(-1); 179 180 if (mxParent.is()) 181 { 182 Reference<XAccessibleContext> xParentContext (mxParent->getAccessibleContext()); 183 if (xParentContext.is()) 184 { 185 sal_Int32 nChildCount (xParentContext->getAccessibleChildCount()); 186 for (sal_Int32 i=0; i<nChildCount; ++i) 187 if (xParentContext->getAccessibleChild(i).get() 188 == static_cast<XAccessible*>(this)) 189 { 190 nIndexInParent = i; 191 break; 192 } 193 } 194 } 195 196 return nIndexInParent; 197 } 198 199 200 201 202 sal_Int16 SAL_CALL AccessibleSlideSorterObject::getAccessibleRole (void) 203 throw (uno::RuntimeException) 204 { 205 ThrowIfDisposed(); 206 static sal_Int16 nRole = AccessibleRole::LIST_ITEM; 207 return nRole; 208 } 209 210 211 212 213 ::rtl::OUString SAL_CALL AccessibleSlideSorterObject::getAccessibleDescription (void) 214 throw (uno::RuntimeException) 215 { 216 ThrowIfDisposed(); 217 return String(SdResId(STR_PAGE)); 218 } 219 220 221 222 223 ::rtl::OUString SAL_CALL AccessibleSlideSorterObject::getAccessibleName (void) 224 throw (uno::RuntimeException) 225 { 226 ThrowIfDisposed(); 227 const vos::OGuard aSolarGuard (Application::GetSolarMutex()); 228 229 SdPage* pPage = GetPage(); 230 if (pPage != NULL) 231 return pPage->GetName(); 232 else 233 return String(); 234 } 235 236 237 238 239 Reference<XAccessibleRelationSet> SAL_CALL 240 AccessibleSlideSorterObject::getAccessibleRelationSet (void) 241 throw (uno::RuntimeException) 242 { 243 ThrowIfDisposed(); 244 return Reference<XAccessibleRelationSet>(); 245 } 246 247 248 249 250 Reference<XAccessibleStateSet> SAL_CALL 251 AccessibleSlideSorterObject::getAccessibleStateSet (void) 252 throw (uno::RuntimeException) 253 { 254 ThrowIfDisposed(); 255 const vos::OGuard aSolarGuard (Application::GetSolarMutex()); 256 ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper(); 257 258 if (mxParent.is()) 259 { 260 // Unconditional states. 261 pStateSet->AddState(AccessibleStateType::SELECTABLE); 262 pStateSet->AddState(AccessibleStateType::FOCUSABLE); 263 pStateSet->AddState(AccessibleStateType::ENABLED); 264 pStateSet->AddState(AccessibleStateType::VISIBLE); 265 pStateSet->AddState(AccessibleStateType::SHOWING); 266 pStateSet->AddState(AccessibleStateType::ACTIVE); 267 pStateSet->AddState(AccessibleStateType::SENSITIVE); 268 269 // Conditional states. 270 if (mrSlideSorter.GetController().GetPageSelector().IsPageSelected(mnPageNumber)) 271 pStateSet->AddState(AccessibleStateType::SELECTED); 272 if (mrSlideSorter.GetController().GetFocusManager().GetFocusedPageIndex() == mnPageNumber) 273 if (mrSlideSorter.GetController().GetFocusManager().IsFocusShowing()) 274 pStateSet->AddState(AccessibleStateType::FOCUSED); 275 } 276 277 return pStateSet; 278 } 279 280 281 282 283 lang::Locale SAL_CALL AccessibleSlideSorterObject::getLocale (void) 284 throw (IllegalAccessibleComponentStateException, 285 RuntimeException) 286 { 287 ThrowIfDisposed(); 288 // Delegate request to parent. 289 if (mxParent.is()) 290 { 291 Reference<XAccessibleContext> xParentContext (mxParent->getAccessibleContext()); 292 if (xParentContext.is()) 293 return xParentContext->getLocale (); 294 } 295 296 // No locale and no parent. Therefore throw exception to indicate this 297 // cluelessness. 298 throw IllegalAccessibleComponentStateException(); 299 } 300 301 302 303 304 305 //===== XAccessibleEventBroadcaster =========================================== 306 307 void SAL_CALL AccessibleSlideSorterObject::addEventListener( 308 const Reference<XAccessibleEventListener>& rxListener) 309 throw (RuntimeException) 310 { 311 if (rxListener.is()) 312 { 313 const osl::MutexGuard aGuard(maMutex); 314 315 if (IsDisposed()) 316 { 317 uno::Reference<uno::XInterface> x ((lang::XComponent *)this, uno::UNO_QUERY); 318 rxListener->disposing (lang::EventObject (x)); 319 } 320 else 321 { 322 if (mnClientId == 0) 323 mnClientId = comphelper::AccessibleEventNotifier::registerClient(); 324 comphelper::AccessibleEventNotifier::addEventListener(mnClientId, rxListener); 325 } 326 } 327 } 328 329 330 331 332 void SAL_CALL AccessibleSlideSorterObject::removeEventListener( 333 const Reference<XAccessibleEventListener>& rxListener) 334 throw (uno::RuntimeException) 335 { 336 ThrowIfDisposed(); 337 if (rxListener.is()) 338 { 339 const osl::MutexGuard aGuard(maMutex); 340 341 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, rxListener ); 342 if ( !nListenerCount ) 343 { 344 // no listeners anymore 345 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), 346 // and at least to us not firing any events anymore, in case somebody calls 347 // NotifyAccessibleEvent, again 348 comphelper::AccessibleEventNotifier::revokeClient( mnClientId ); 349 mnClientId = 0; 350 } 351 } 352 } 353 354 355 356 357 //===== XAccessibleComponent ================================================== 358 359 sal_Bool SAL_CALL AccessibleSlideSorterObject::containsPoint(const awt::Point& aPoint) 360 throw (uno::RuntimeException) 361 { 362 ThrowIfDisposed(); 363 const awt::Size aSize (getSize()); 364 return (aPoint.X >= 0) 365 && (aPoint.X < aSize.Width) 366 && (aPoint.Y >= 0) 367 && (aPoint.Y < aSize.Height); 368 } 369 370 371 372 373 Reference<XAccessible> SAL_CALL 374 AccessibleSlideSorterObject::getAccessibleAtPoint(const awt::Point& ) 375 throw (uno::RuntimeException) 376 { 377 return NULL; 378 } 379 380 381 382 383 awt::Rectangle SAL_CALL AccessibleSlideSorterObject::getBounds (void) 384 throw (RuntimeException) 385 { 386 ThrowIfDisposed (); 387 388 const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 389 390 Rectangle aBBox ( 391 mrSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetBoundingBox( 392 mrSlideSorter.GetModel().GetPageDescriptor(mnPageNumber), 393 ::sd::slidesorter::view::PageObjectLayouter::PageObject, 394 ::sd::slidesorter::view::PageObjectLayouter::WindowCoordinateSystem)); 395 396 if (mxParent.is()) 397 { 398 Reference<XAccessibleComponent> xParentComponent(mxParent->getAccessibleContext(), UNO_QUERY); 399 if (xParentComponent.is()) 400 { 401 awt::Rectangle aParentBBox (xParentComponent->getBounds()); 402 aBBox.Intersection(Rectangle( 403 aParentBBox.X, 404 aParentBBox.Y, 405 aParentBBox.Width, 406 aParentBBox.Height)); 407 } 408 } 409 410 return awt::Rectangle( 411 aBBox.Left(), 412 aBBox.Top(), 413 aBBox.GetWidth(), 414 aBBox.GetHeight()); 415 } 416 417 418 419 420 awt::Point SAL_CALL AccessibleSlideSorterObject::getLocation () 421 throw (RuntimeException) 422 { 423 ThrowIfDisposed (); 424 const awt::Rectangle aBBox (getBounds()); 425 return awt::Point(aBBox.X, aBBox.Y); 426 } 427 428 429 430 431 awt::Point SAL_CALL AccessibleSlideSorterObject::getLocationOnScreen (void) 432 throw (RuntimeException) 433 { 434 ThrowIfDisposed (); 435 436 const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 437 438 awt::Point aLocation (getLocation()); 439 440 if (mxParent.is()) 441 { 442 Reference<XAccessibleComponent> xParentComponent(mxParent->getAccessibleContext(),UNO_QUERY); 443 if (xParentComponent.is()) 444 { 445 const awt::Point aParentLocationOnScreen(xParentComponent->getLocationOnScreen()); 446 aLocation.X += aParentLocationOnScreen.X; 447 aLocation.Y += aParentLocationOnScreen.Y; 448 } 449 } 450 451 return aLocation; 452 } 453 454 455 456 457 awt::Size SAL_CALL AccessibleSlideSorterObject::getSize (void) 458 throw (RuntimeException) 459 { 460 ThrowIfDisposed (); 461 const awt::Rectangle aBBox (getBounds()); 462 return awt::Size(aBBox.Width,aBBox.Height); 463 } 464 465 466 467 468 void SAL_CALL AccessibleSlideSorterObject::grabFocus (void) 469 throw (RuntimeException) 470 { 471 // nothing to do 472 } 473 474 475 476 477 sal_Int32 SAL_CALL AccessibleSlideSorterObject::getForeground (void) 478 throw (::com::sun::star::uno::RuntimeException) 479 { 480 ThrowIfDisposed (); 481 svtools::ColorConfig aColorConfig; 482 sal_uInt32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor; 483 return static_cast<sal_Int32>(nColor); 484 } 485 486 487 488 489 sal_Int32 SAL_CALL AccessibleSlideSorterObject::getBackground (void) 490 throw (::com::sun::star::uno::RuntimeException) 491 { 492 ThrowIfDisposed (); 493 sal_uInt32 nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor(); 494 return static_cast<sal_Int32>(nColor); 495 } 496 497 498 499 500 501 //===== XServiceInfo ======================================================== 502 503 ::rtl::OUString SAL_CALL 504 AccessibleSlideSorterObject::getImplementationName (void) 505 throw (::com::sun::star::uno::RuntimeException) 506 { 507 return OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleSlideSorterObject")); 508 } 509 510 511 512 513 sal_Bool SAL_CALL 514 AccessibleSlideSorterObject::supportsService (const OUString& sServiceName) 515 throw (::com::sun::star::uno::RuntimeException) 516 { 517 ThrowIfDisposed (); 518 519 // Iterate over all supported service names and return true if on of them 520 // matches the given name. 521 uno::Sequence< ::rtl::OUString> aSupportedServices ( 522 getSupportedServiceNames ()); 523 for (int i=0; i<aSupportedServices.getLength(); i++) 524 if (sServiceName == aSupportedServices[i]) 525 return sal_True; 526 return sal_False; 527 } 528 529 530 531 532 uno::Sequence< ::rtl::OUString> SAL_CALL 533 AccessibleSlideSorterObject::getSupportedServiceNames (void) 534 throw (::com::sun::star::uno::RuntimeException) 535 { 536 ThrowIfDisposed (); 537 538 static const OUString sServiceNames[2] = { 539 OUString(RTL_CONSTASCII_USTRINGPARAM( 540 "com.sun.star.accessibility.Accessible")), 541 OUString(RTL_CONSTASCII_USTRINGPARAM( 542 "com.sun.star.accessibility.AccessibleContext")) 543 }; 544 return uno::Sequence<OUString> (sServiceNames, 2); 545 } 546 547 548 549 550 void AccessibleSlideSorterObject::ThrowIfDisposed (void) 551 throw (lang::DisposedException) 552 { 553 if (rBHelper.bDisposed || rBHelper.bInDispose) 554 { 555 OSL_TRACE ("Calling disposed object. Throwing exception:"); 556 throw lang::DisposedException ( 557 OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")), 558 static_cast<uno::XWeak*>(this)); 559 } 560 } 561 562 563 564 sal_Bool AccessibleSlideSorterObject::IsDisposed (void) 565 { 566 return (rBHelper.bDisposed || rBHelper.bInDispose); 567 } 568 569 570 571 572 SdPage* AccessibleSlideSorterObject::GetPage (void) const 573 { 574 ::sd::slidesorter::model::SharedPageDescriptor pDescriptor( 575 mrSlideSorter.GetModel().GetPageDescriptor(mnPageNumber)); 576 if (pDescriptor.get() != NULL) 577 return pDescriptor->GetPage(); 578 else 579 return NULL; 580 } 581 582 583 } // end of namespace ::accessibility 584