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_sc.hxx" 26 27 28 #include "AccessibleDocument.hxx" 29 #include "AccessibleSpreadsheet.hxx" 30 #include "tabvwsh.hxx" 31 #include "AccessibilityHints.hxx" 32 #include "document.hxx" 33 #include "drwlayer.hxx" 34 #include "unoguard.hxx" 35 #include "shapeuno.hxx" 36 #include "DrawModelBroadcaster.hxx" 37 #include "drawview.hxx" 38 #include "gridwin.hxx" 39 #include "AccessibleEditObject.hxx" 40 #include "scresid.hxx" 41 #ifndef SC_SC_HRC 42 #include "sc.hrc" 43 #endif 44 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 45 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_ 46 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 47 #endif 48 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLERELATIONTYPE_HPP_ 49 #include <com/sun/star/accessibility/AccessibleRelationType.hpp> 50 #endif 51 #include <com/sun/star/view/XSelectionSupplier.hpp> 52 #include <com/sun/star/drawing/XShape.hpp> 53 #include <com/sun/star/drawing/XShapes.hpp> 54 55 #ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX 56 #include <unotools/accessiblestatesethelper.hxx> 57 #endif 58 #include <tools/debug.hxx> 59 #include <tools/gen.hxx> 60 #include <svx/svdpage.hxx> 61 #include <svx/svdobj.hxx> 62 #include <svx/ShapeTypeHandler.hxx> 63 #include <svx/AccessibleShape.hxx> 64 #include <svx/AccessibleShapeTreeInfo.hxx> 65 #include <svx/AccessibleShapeInfo.hxx> 66 #include <comphelper/sequence.hxx> 67 #include <sfx2/viewfrm.hxx> 68 #include <svx/unoshcol.hxx> 69 #include <svx/unoshape.hxx> 70 #include <unotools/accessiblerelationsethelper.hxx> 71 #include <toolkit/helper/convert.hxx> 72 73 #include <svx/AccessibleControlShape.hxx> 74 #include <svx/AccessibleShape.hxx> 75 #include <svx/ShapeTypeHandler.hxx> 76 #include <svx/SvxShapeTypes.hxx> 77 #include <sfx2/objsh.hxx> 78 #include <editeng/editview.hxx> 79 #include <editeng/editeng.hxx> 80 #include <list> 81 #include <algorithm> 82 #include "AccessibleCell.hxx" 83 84 #include "svx/unoapi.hxx" 85 #include "scmod.hxx" 86 using namespace ::com::sun::star; 87 using namespace ::com::sun::star::accessibility; 88 using ::std::for_each; 89 90 //===== internal ======================================================== 91 92 struct ScAccessibleShapeData 93 { 94 ScAccessibleShapeData() : pAccShape(NULL), pRelationCell(NULL), bSelected(sal_False), bSelectable(sal_True) {} 95 ~ScAccessibleShapeData(); 96 mutable ::accessibility::AccessibleShape* pAccShape; 97 mutable ScAddress* pRelationCell; // if it is NULL this shape is anchored on the table 98 // SdrObject* pShape; 99 com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xShape; 100 mutable sal_Bool bSelected; 101 sal_Bool bSelectable; 102 }; 103 104 ScAccessibleShapeData::~ScAccessibleShapeData() 105 { 106 if (pAccShape) 107 { 108 pAccShape->dispose(); 109 pAccShape->release(); 110 } 111 } 112 113 struct ScShapeDataLess 114 { 115 rtl::OUString msLayerId; 116 rtl::OUString msZOrder; 117 ScShapeDataLess() 118 : msLayerId(RTL_CONSTASCII_USTRINGPARAM( "LayerID" )), 119 msZOrder(RTL_CONSTASCII_USTRINGPARAM( "ZOrder" )) 120 { 121 } 122 void ConvertLayerId(sal_Int16& rLayerID) const // changes the number of the LayerId so it the accessibility order 123 { 124 switch (rLayerID) 125 { 126 case SC_LAYER_FRONT: 127 rLayerID = 1; 128 break; 129 case SC_LAYER_BACK: 130 rLayerID = 0; 131 break; 132 case SC_LAYER_INTERN: 133 rLayerID = 2; 134 break; 135 case SC_LAYER_CONTROLS: 136 rLayerID = 3; 137 break; 138 } 139 } 140 sal_Bool LessThanSheet(const ScAccessibleShapeData* pData) const 141 { 142 sal_Bool bResult(sal_False); 143 uno::Reference< beans::XPropertySet> xProps(pData->xShape, uno::UNO_QUERY); 144 if (xProps.is()) 145 { 146 uno::Any aPropAny = xProps->getPropertyValue(msLayerId); 147 sal_Int16 nLayerID = 0; 148 if( (aPropAny >>= nLayerID) ) 149 { 150 if (nLayerID == SC_LAYER_BACK) 151 bResult = sal_True; 152 } 153 } 154 return bResult; 155 } 156 sal_Bool operator()(const ScAccessibleShapeData* pData1, const ScAccessibleShapeData* pData2) const 157 { 158 sal_Bool bResult(sal_False); 159 if (pData1 && pData2) 160 { 161 uno::Reference< beans::XPropertySet> xProps1(pData1->xShape, uno::UNO_QUERY); 162 uno::Reference< beans::XPropertySet> xProps2(pData2->xShape, uno::UNO_QUERY); 163 if (xProps1.is() && xProps2.is()) 164 { 165 uno::Any aPropAny1 = xProps1->getPropertyValue(msLayerId); 166 uno::Any aPropAny2 = xProps2->getPropertyValue(msLayerId); 167 sal_Int16 nLayerID1(0); 168 sal_Int16 nLayerID2(0); 169 if( (aPropAny1 >>= nLayerID1) && (aPropAny2 >>= nLayerID2) ) 170 { 171 if (nLayerID1 == nLayerID2) 172 { 173 uno::Any aAny1 = xProps1->getPropertyValue(msZOrder); 174 sal_Int32 nZOrder1 = 0; 175 uno::Any aAny2 = xProps2->getPropertyValue(msZOrder); 176 sal_Int32 nZOrder2 = 0; 177 if ( (aAny1 >>= nZOrder1) && (aAny2 >>= nZOrder2) ) 178 bResult = (nZOrder1 < nZOrder2); 179 } 180 else 181 { 182 ConvertLayerId(nLayerID1); 183 ConvertLayerId(nLayerID2); 184 bResult = (nLayerID1 < nLayerID2); 185 } 186 } 187 } 188 } 189 else if (pData1 && !pData2) 190 bResult = LessThanSheet(pData1); 191 else if (!pData1 && pData2) 192 bResult = !LessThanSheet(pData2); 193 else 194 bResult = sal_False; 195 return bResult; 196 } 197 }; 198 199 struct DeselectShape 200 { 201 void operator() (const ScAccessibleShapeData* pAccShapeData) const 202 { 203 if (pAccShapeData) 204 { 205 pAccShapeData->bSelected = sal_False; 206 if (pAccShapeData->pAccShape) 207 pAccShapeData->pAccShape->ResetState(AccessibleStateType::SELECTED); 208 } 209 } 210 }; 211 212 struct SelectShape 213 { 214 uno::Reference < drawing::XShapes > xShapes; 215 SelectShape(uno::Reference<drawing::XShapes>& xTemp) : xShapes(xTemp) {} 216 void operator() (const ScAccessibleShapeData* pAccShapeData) const 217 { 218 if (pAccShapeData && pAccShapeData->bSelectable) 219 { 220 pAccShapeData->bSelected = sal_True; 221 if (pAccShapeData->pAccShape) 222 pAccShapeData->pAccShape->SetState(AccessibleStateType::SELECTED); 223 if (xShapes.is()) 224 xShapes->add(pAccShapeData->xShape); 225 } 226 } 227 }; 228 229 struct Destroy 230 { 231 void operator() (ScAccessibleShapeData* pData) 232 { 233 if (pData) 234 DELETEZ(pData); 235 } 236 }; 237 238 class ScChildrenShapes : public SfxListener, 239 public ::accessibility::IAccessibleParent 240 { 241 public: 242 ScChildrenShapes(ScAccessibleDocument* pAccessibleDocument, ScTabViewShell* pViewShell, ScSplitPos eSplitPos); 243 ~ScChildrenShapes(); 244 245 ///===== SfxListener ===================================================== 246 247 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); 248 249 ///===== IAccessibleParent =============================================== 250 251 virtual sal_Bool ReplaceChild ( 252 ::accessibility::AccessibleShape* pCurrentChild, 253 const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape, 254 const long _nIndex, 255 const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo 256 ) throw (::com::sun::star::uno::RuntimeException); 257 258 virtual ::accessibility::AccessibleControlShape* GetAccControlShapeFromModel 259 (::com::sun::star::beans::XPropertySet* pSet) 260 throw (::com::sun::star::uno::RuntimeException); 261 virtual ::com::sun::star::uno::Reference< 262 ::com::sun::star::accessibility::XAccessible> 263 GetAccessibleCaption (const ::com::sun::star::uno::Reference< 264 ::com::sun::star::drawing::XShape>& xShape) 265 throw (::com::sun::star::uno::RuntimeException); 266 ///===== Internal ======================================================== 267 void SetDrawBroadcaster(); 268 269 sal_Int32 GetCount() const; 270 uno::Reference< XAccessible > Get(const ScAccessibleShapeData* pData) const; 271 uno::Reference< XAccessible > Get(sal_Int32 nIndex) const; 272 uno::Reference< XAccessible > GetAt(const awt::Point& rPoint) const; 273 274 // gets the index of the shape starting on 0 (without the index of the table) 275 // returns the selected shape 276 sal_Bool IsSelected(sal_Int32 nIndex, 277 com::sun::star::uno::Reference<com::sun::star::drawing::XShape>& rShape) const; 278 279 sal_Bool SelectionChanged(); 280 281 void Select(sal_Int32 nIndex); 282 void DeselectAll(); // deselect also the table 283 void SelectAll(); 284 sal_Int32 GetSelectedCount() const; 285 uno::Reference< XAccessible > GetSelected(sal_Int32 nSelectedChildIndex, sal_Bool bTabSelected) const; 286 void Deselect(sal_Int32 nChildIndex); 287 288 SdrPage* GetDrawPage() const; 289 290 utl::AccessibleRelationSetHelper* GetRelationSet(const ScAddress* pAddress) const; 291 292 void VisAreaChanged() const; 293 private: 294 typedef std::vector<ScAccessibleShapeData*> SortedShapes; 295 296 mutable SortedShapes maZOrderedShapes; // a null pointer represents the sheet in the correct order 297 298 mutable ::accessibility::AccessibleShapeTreeInfo maShapeTreeInfo; 299 mutable com::sun::star::uno::Reference<com::sun::star::view::XSelectionSupplier> xSelectionSupplier; 300 mutable sal_uInt32 mnSdrObjCount; 301 mutable sal_uInt32 mnShapesSelected; 302 ScTabViewShell* mpViewShell; 303 ScAccessibleDocument* mpAccessibleDocument; 304 ScSplitPos meSplitPos; 305 306 void FillShapes(std::vector < uno::Reference < drawing::XShape > >& rShapes) const; 307 sal_Bool FindSelectedShapesChanges(const com::sun::star::uno::Reference<com::sun::star::drawing::XShapes>& xShapes, sal_Bool bCommitChange) const; 308 void FillSelectionSupplier() const; 309 310 ScAddress* GetAnchor(const uno::Reference<drawing::XShape>& xShape) const; 311 uno::Reference<XAccessibleRelationSet> GetRelationSet(const ScAccessibleShapeData* pData) const; 312 void CheckWhetherAnchorChanged(const uno::Reference<drawing::XShape>& xShape) const; 313 void SetAnchor(const uno::Reference<drawing::XShape>& xShape, ScAccessibleShapeData* pData) const; 314 void AddShape(const uno::Reference<drawing::XShape>& xShape, sal_Bool bCommitChange) const; 315 void RemoveShape(const uno::Reference<drawing::XShape>& xShape) const; 316 317 sal_Bool FindShape(const uno::Reference<drawing::XShape>& xShape, SortedShapes::iterator& rItr) const; 318 319 sal_Int8 Compare(const ScAccessibleShapeData* pData1, 320 const ScAccessibleShapeData* pData2) const; 321 }; 322 323 ScChildrenShapes::ScChildrenShapes(ScAccessibleDocument* pAccessibleDocument, ScTabViewShell* pViewShell, ScSplitPos eSplitPos) 324 : 325 mnShapesSelected(0), 326 mpViewShell(pViewShell), 327 mpAccessibleDocument(pAccessibleDocument), 328 meSplitPos(eSplitPos) 329 { 330 FillSelectionSupplier(); 331 maZOrderedShapes.push_back(NULL); // add an element which represents the table 332 333 GetCount(); // fill list with filtered shapes (no internal shapes) 334 335 if (mnShapesSelected) 336 { 337 //set flag on every selected shape 338 if (!xSelectionSupplier.is()) 339 throw uno::RuntimeException(); 340 341 uno::Reference<drawing::XShapes> xShapes(xSelectionSupplier->getSelection(), uno::UNO_QUERY); 342 if (xShapes.is()) 343 FindSelectedShapesChanges(xShapes, sal_False); 344 } 345 if (pViewShell) 346 { 347 SfxBroadcaster* pDrawBC = pViewShell->GetViewData()->GetDocument()->GetDrawBroadcaster(); 348 if (pDrawBC) 349 { 350 StartListening(*pDrawBC); 351 352 maShapeTreeInfo.SetModelBroadcaster( new ScDrawModelBroadcaster(pViewShell->GetViewData()->GetDocument()->GetDrawLayer()) ); 353 maShapeTreeInfo.SetSdrView(pViewShell->GetViewData()->GetScDrawView()); 354 maShapeTreeInfo.SetController(NULL); 355 maShapeTreeInfo.SetWindow(pViewShell->GetWindowByPos(meSplitPos)); 356 maShapeTreeInfo.SetViewForwarder(mpAccessibleDocument); 357 } 358 } 359 } 360 361 ScChildrenShapes::~ScChildrenShapes() 362 { 363 std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), Destroy()); 364 if (mpViewShell) 365 { 366 SfxBroadcaster* pDrawBC = mpViewShell->GetViewData()->GetDocument()->GetDrawBroadcaster(); 367 if (pDrawBC) 368 EndListening(*pDrawBC); 369 } 370 } 371 372 void ScChildrenShapes::SetDrawBroadcaster() 373 { 374 if (mpViewShell) 375 { 376 SfxBroadcaster* pDrawBC = mpViewShell->GetViewData()->GetDocument()->GetDrawBroadcaster(); 377 if (pDrawBC) 378 { 379 StartListening(*pDrawBC, sal_True); 380 381 maShapeTreeInfo.SetModelBroadcaster( new ScDrawModelBroadcaster(mpViewShell->GetViewData()->GetDocument()->GetDrawLayer()) ); 382 maShapeTreeInfo.SetSdrView(mpViewShell->GetViewData()->GetScDrawView()); 383 maShapeTreeInfo.SetController(NULL); 384 maShapeTreeInfo.SetWindow(mpViewShell->GetWindowByPos(meSplitPos)); 385 maShapeTreeInfo.SetViewForwarder(mpAccessibleDocument); 386 } 387 } 388 } 389 390 void ScChildrenShapes::Notify(SfxBroadcaster&, const SfxHint& rHint) 391 { 392 if ( rHint.ISA( SdrHint ) ) 393 { 394 const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint ); 395 if (pSdrHint) 396 { 397 SdrObject* pObj = const_cast<SdrObject*>(pSdrHint->GetObject()); 398 if (pObj && /*(pObj->GetLayer() != SC_LAYER_INTERN) && */(pObj->GetPage() == GetDrawPage()) && 399 (pObj->GetPage() == pObj->GetObjList()) ) //#108480# only do something if the object lies direct on the page 400 { 401 switch (pSdrHint->GetKind()) 402 { 403 case HINT_OBJCHG : // Objekt geaendert 404 { 405 uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY); 406 if (xShape.is()) 407 { 408 ScShapeDataLess aLess; 409 std::sort(maZOrderedShapes.begin(), maZOrderedShapes.end(), aLess); // sort, because the z index or layer could be changed 410 CheckWhetherAnchorChanged(xShape); 411 } 412 } 413 break; 414 case HINT_OBJINSERTED : // Neues Zeichenobjekt eingefuegt 415 { 416 uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY); 417 if (xShape.is()) 418 AddShape(xShape, sal_True); 419 } 420 break; 421 case HINT_OBJREMOVED : // Zeichenobjekt aus Liste entfernt 422 { 423 uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY); 424 if (xShape.is()) 425 RemoveShape(xShape); 426 } 427 break; 428 default : 429 { 430 // other events are not interesting 431 } 432 break; 433 } 434 } 435 } 436 } 437 } 438 439 sal_Bool ScChildrenShapes::ReplaceChild (::accessibility::AccessibleShape* pCurrentChild, 440 const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape, 441 const long _nIndex, const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo) 442 throw (uno::RuntimeException) 443 { 444 // create the new child 445 ::accessibility::AccessibleShape* pReplacement = ::accessibility::ShapeTypeHandler::Instance().CreateAccessibleObject ( 446 ::accessibility::AccessibleShapeInfo ( _rxShape, pCurrentChild->getAccessibleParent(), this, _nIndex ), 447 _rShapeTreeInfo 448 ); 449 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xNewChild( pReplacement ); // keep this alive (do this before calling Init!) 450 if ( pReplacement ) 451 pReplacement->Init(); 452 453 sal_Bool bResult(sal_False); 454 if (pCurrentChild && pReplacement) 455 { 456 DBG_ASSERT(pCurrentChild->GetXShape().get() == pReplacement->GetXShape().get(), "XShape changes and should be inserted sorted"); 457 SortedShapes::iterator aItr; 458 FindShape(pCurrentChild->GetXShape(), aItr); 459 if (aItr != maZOrderedShapes.end() && (*aItr)) 460 { 461 if ((*aItr)->pAccShape) 462 { 463 DBG_ASSERT((*aItr)->pAccShape == pCurrentChild, "wrong child found"); 464 AccessibleEventObject aEvent; 465 aEvent.EventId = AccessibleEventId::CHILD; 466 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument); 467 aEvent.OldValue <<= uno::makeAny(uno::Reference<XAccessible>(pCurrentChild)); 468 469 mpAccessibleDocument->CommitChange(aEvent); // child is gone - event 470 471 pCurrentChild->dispose(); 472 } 473 (*aItr)->pAccShape = pReplacement; 474 AccessibleEventObject aEvent; 475 aEvent.EventId = AccessibleEventId::CHILD; 476 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument); 477 aEvent.NewValue <<= uno::makeAny(uno::Reference<XAccessible>(pReplacement)); 478 479 mpAccessibleDocument->CommitChange(aEvent); // child is new - event 480 bResult = sal_True; 481 } 482 } 483 return bResult; 484 } 485 486 ::accessibility::AccessibleControlShape * ScChildrenShapes::GetAccControlShapeFromModel(::com::sun::star::beans::XPropertySet* pSet) throw (::com::sun::star::uno::RuntimeException) 487 { 488 sal_Int32 count = GetCount(); 489 for (sal_Int32 index=0;index<count;index++) 490 { 491 ScAccessibleShapeData* pShape = maZOrderedShapes[index]; 492 if (pShape) 493 { 494 ::accessibility::AccessibleShape* pAccShape = pShape->pAccShape; 495 if (pAccShape && ::accessibility::ShapeTypeHandler::Instance().GetTypeId (pAccShape->GetXShape()) == ::accessibility::DRAWING_CONTROL) 496 { 497 ::accessibility::AccessibleControlShape *pCtlAccShape = static_cast < ::accessibility::AccessibleControlShape* >(pAccShape); 498 if (pCtlAccShape && pCtlAccShape->GetControlModel() == pSet) 499 return pCtlAccShape; 500 } 501 } 502 } 503 return NULL; 504 } 505 ::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessible > 506 ScChildrenShapes::GetAccessibleCaption (const ::com::sun::star::uno::Reference < ::com::sun::star::drawing::XShape>& xShape) 507 throw (::com::sun::star::uno::RuntimeException) 508 { 509 sal_Int32 count = GetCount(); 510 for (sal_Int32 index=0;index<count;index++) 511 { 512 ScAccessibleShapeData* pShape = maZOrderedShapes[index]; 513 if (pShape && pShape->xShape == xShape ) 514 { 515 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xNewChild( pShape->pAccShape ); 516 // uno::Reference<XAccessible> xNewChild( pShape->pAccShape , uno::UNO_QUERY ); 517 if(xNewChild.get()) 518 return xNewChild; 519 } 520 } 521 return NULL; 522 } 523 sal_Int32 ScChildrenShapes::GetCount() const 524 { 525 SdrPage* pDrawPage = GetDrawPage(); 526 if (pDrawPage && (maZOrderedShapes.size() == 1)) // the table is always in 527 { 528 mnSdrObjCount = pDrawPage->GetObjCount(); 529 maZOrderedShapes.reserve(mnSdrObjCount + 1); // the table is always in 530 for (sal_uInt32 i = 0; i < mnSdrObjCount; ++i) 531 { 532 SdrObject* pObj = pDrawPage->GetObj(i); 533 if (pObj/* && (pObj->GetLayer() != SC_LAYER_INTERN)*/) 534 { 535 uno::Reference< drawing::XShape > xShape (pObj->getUnoShape(), uno::UNO_QUERY); 536 AddShape(xShape, sal_False); //inserts in the correct order 537 } 538 } 539 } 540 return maZOrderedShapes.size(); 541 } 542 543 uno::Reference< XAccessible > ScChildrenShapes::Get(const ScAccessibleShapeData* pData) const 544 { 545 if (!pData) 546 return NULL; 547 548 if (!pData->pAccShape) 549 { 550 ::accessibility::ShapeTypeHandler& rShapeHandler = ::accessibility::ShapeTypeHandler::Instance(); 551 ::accessibility::AccessibleShapeInfo aShapeInfo(pData->xShape, mpAccessibleDocument, const_cast<ScChildrenShapes*>(this)); 552 pData->pAccShape = rShapeHandler.CreateAccessibleObject( 553 aShapeInfo, maShapeTreeInfo); 554 if (pData->pAccShape) 555 { 556 pData->pAccShape->acquire(); 557 pData->pAccShape->Init(); 558 if (pData->bSelected) 559 pData->pAccShape->SetState(AccessibleStateType::SELECTED); 560 if (!pData->bSelectable) 561 pData->pAccShape->ResetState(AccessibleStateType::SELECTABLE); 562 pData->pAccShape->SetRelationSet(GetRelationSet(pData)); 563 } 564 } 565 return pData->pAccShape; 566 } 567 568 uno::Reference< XAccessible > ScChildrenShapes::Get(sal_Int32 nIndex) const 569 { 570 if (maZOrderedShapes.size() <= 1) 571 GetCount(); // fill list with filtered shapes (no internal shapes) 572 573 if (static_cast<sal_uInt32>(nIndex) >= maZOrderedShapes.size()) 574 return NULL; 575 576 return Get(maZOrderedShapes[nIndex]); 577 } 578 579 uno::Reference< XAccessible > ScChildrenShapes::GetAt(const awt::Point& rPoint) const 580 { 581 uno::Reference<XAccessible> xAccessible; 582 if(mpViewShell) 583 { 584 sal_Int32 i(maZOrderedShapes.size() - 1); 585 sal_Bool bFound(sal_False); 586 while (!bFound && i >= 0) 587 { 588 ScAccessibleShapeData* pShape = maZOrderedShapes[i]; 589 if (pShape) 590 { 591 if (!pShape->pAccShape) 592 Get(pShape); 593 594 if (pShape->pAccShape) 595 { 596 Point aPoint(VCLPoint(rPoint)); 597 aPoint -= VCLRectangle(pShape->pAccShape->getBounds()).TopLeft(); 598 if (pShape->pAccShape->containsPoint(AWTPoint(aPoint))) 599 { 600 xAccessible = pShape->pAccShape; 601 bFound = sal_True; 602 } 603 } 604 else 605 { 606 DBG_ERRORFILE("I should have an accessible shape now!"); 607 } 608 } 609 else 610 bFound = sal_True; // this is the sheet and it lies before the rest of the shapes which are background shapes 611 612 --i; 613 } 614 } 615 return xAccessible; 616 } 617 618 sal_Bool ScChildrenShapes::IsSelected(sal_Int32 nIndex, 619 uno::Reference<drawing::XShape>& rShape) const 620 { 621 sal_Bool bResult (sal_False); 622 if (maZOrderedShapes.size() <= 1) 623 GetCount(); // fill list with filtered shapes (no internal shapes) 624 625 if (!xSelectionSupplier.is()) 626 throw uno::RuntimeException(); 627 628 if (!maZOrderedShapes[nIndex]) 629 return sal_False; 630 631 bResult = maZOrderedShapes[nIndex]->bSelected; 632 rShape = maZOrderedShapes[nIndex]->xShape; 633 634 #ifdef DBG_UTIL // test whether it is truly selected by a slower method 635 uno::Reference< drawing::XShape > xReturnShape; 636 sal_Bool bDebugResult(sal_False); 637 uno::Reference<container::XIndexAccess> xIndexAccess; 638 xSelectionSupplier->getSelection() >>= xIndexAccess; 639 640 if (xIndexAccess.is()) 641 { 642 sal_Int32 nCount(xIndexAccess->getCount()); 643 if (nCount) 644 { 645 uno::Reference< drawing::XShape > xShape; 646 uno::Reference< drawing::XShape > xIndexShape = maZOrderedShapes[nIndex]->xShape; 647 sal_Int32 i(0); 648 while (!bDebugResult && (i < nCount)) 649 { 650 xIndexAccess->getByIndex(i) >>= xShape; 651 if (xShape.is() && (xIndexShape.get() == xShape.get())) 652 { 653 bDebugResult = sal_True; 654 xReturnShape = xShape; 655 } 656 else 657 ++i; 658 } 659 } 660 } 661 DBG_ASSERT((bResult == bDebugResult) && ((bResult && (rShape.get() == xReturnShape.get())) || !bResult), "found the wrong shape or result"); 662 #endif 663 664 return bResult; 665 } 666 667 sal_Bool ScChildrenShapes::SelectionChanged() 668 { 669 sal_Bool bResult(sal_False); 670 if (!xSelectionSupplier.is()) 671 throw uno::RuntimeException(); 672 673 uno::Reference<drawing::XShapes> xShapes(xSelectionSupplier->getSelection(), uno::UNO_QUERY); 674 675 bResult = FindSelectedShapesChanges(xShapes, sal_True); 676 677 return bResult; 678 } 679 680 void ScChildrenShapes::Select(sal_Int32 nIndex) 681 { 682 if (maZOrderedShapes.size() <= 1) 683 GetCount(); // fill list with filtered shapes (no internal shapes) 684 685 if (!xSelectionSupplier.is()) 686 throw uno::RuntimeException(); 687 688 if (!maZOrderedShapes[nIndex]) 689 return; 690 691 uno::Reference<drawing::XShape> xShape; 692 if (!IsSelected(nIndex, xShape) && maZOrderedShapes[nIndex]->bSelectable) 693 { 694 uno::Reference<drawing::XShapes> xShapes; 695 xSelectionSupplier->getSelection() >>= xShapes; 696 697 if (!xShapes.is()) 698 xShapes = new SvxShapeCollection(); 699 700 xShapes->add(maZOrderedShapes[nIndex]->xShape); 701 702 try 703 { 704 xSelectionSupplier->select(uno::makeAny(xShapes)); 705 maZOrderedShapes[nIndex]->bSelected = sal_True; 706 if (maZOrderedShapes[nIndex]->pAccShape) 707 maZOrderedShapes[nIndex]->pAccShape->SetState(AccessibleStateType::SELECTED); 708 } 709 catch (lang::IllegalArgumentException&) 710 { 711 } 712 } 713 } 714 715 void ScChildrenShapes::DeselectAll() 716 { 717 if (!xSelectionSupplier.is()) 718 throw uno::RuntimeException(); 719 720 sal_Bool bSomethingSelected(sal_True); 721 try 722 { 723 xSelectionSupplier->select(uno::Any()); //deselects all 724 } 725 catch (lang::IllegalArgumentException&) 726 { 727 DBG_ERRORFILE("nothing selected before"); 728 bSomethingSelected = sal_False; 729 } 730 731 if (bSomethingSelected) 732 std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), DeselectShape()); 733 } 734 735 void ScChildrenShapes::SelectAll() 736 { 737 if (!xSelectionSupplier.is()) 738 throw uno::RuntimeException(); 739 740 if (maZOrderedShapes.size() <= 1) 741 GetCount(); // fill list with filtered shapes (no internal shapes) 742 743 if (maZOrderedShapes.size() > 1) 744 { 745 uno::Reference<drawing::XShapes> xShapes; 746 xShapes = new SvxShapeCollection(); 747 748 try 749 { 750 std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), SelectShape(xShapes)); 751 xSelectionSupplier->select(uno::makeAny(xShapes)); 752 } 753 catch (lang::IllegalArgumentException&) 754 { 755 SelectionChanged(); // find all selected shapes and set the flags 756 } 757 } 758 } 759 760 void ScChildrenShapes::FillShapes(std::vector < uno::Reference < drawing::XShape > >& rShapes) const 761 { 762 uno::Reference<container::XIndexAccess> xIndexAccess; 763 xSelectionSupplier->getSelection() >>= xIndexAccess; 764 765 if (xIndexAccess.is()) 766 { 767 sal_uInt32 nCount(xIndexAccess->getCount()); 768 for (sal_uInt32 i = 0; i < nCount; ++i) 769 { 770 uno::Reference<drawing::XShape> xShape; 771 xIndexAccess->getByIndex(i) >>= xShape; 772 if (xShape.is()) 773 rShapes.push_back(xShape); 774 } 775 } 776 } 777 778 sal_Int32 ScChildrenShapes::GetSelectedCount() const 779 { 780 if (!xSelectionSupplier.is()) 781 throw uno::RuntimeException(); 782 783 std::vector < uno::Reference < drawing::XShape > > aShapes; 784 FillShapes(aShapes); 785 786 return aShapes.size(); 787 } 788 789 uno::Reference< XAccessible > ScChildrenShapes::GetSelected(sal_Int32 nSelectedChildIndex, sal_Bool bTabSelected) const 790 { 791 uno::Reference< XAccessible > xAccessible; 792 793 if (maZOrderedShapes.size() <= 1) 794 GetCount(); // fill list with shapes 795 796 if (!bTabSelected) 797 { 798 std::vector < uno::Reference < drawing::XShape > > aShapes; 799 FillShapes(aShapes); 800 801 if(aShapes.size()<=0) return xAccessible; 802 SortedShapes::iterator aItr; 803 if (FindShape(aShapes[nSelectedChildIndex], aItr)) 804 xAccessible = Get(aItr - maZOrderedShapes.begin()); 805 } 806 else 807 { 808 SortedShapes::iterator aItr = maZOrderedShapes.begin(); 809 SortedShapes::iterator aEndItr = maZOrderedShapes.end(); 810 sal_Bool bFound(sal_False); 811 while(!bFound && aItr != aEndItr) 812 { 813 if (*aItr) 814 { 815 if ((*aItr)->bSelected) 816 { 817 if (nSelectedChildIndex == 0) 818 bFound = sal_True; 819 else 820 --nSelectedChildIndex; 821 } 822 } 823 else 824 { 825 if (nSelectedChildIndex == 0) 826 bFound = sal_True; 827 else 828 --nSelectedChildIndex; 829 } 830 if (!bFound) 831 ++aItr; 832 } 833 if (bFound && *aItr) 834 xAccessible = (*aItr)->pAccShape; 835 } 836 837 return xAccessible; 838 } 839 840 void ScChildrenShapes::Deselect(sal_Int32 nChildIndex) 841 { 842 uno::Reference<drawing::XShape> xShape; 843 if (IsSelected(nChildIndex, xShape)) // returns false if it is the sheet 844 { 845 if (xShape.is()) 846 { 847 uno::Reference<drawing::XShapes> xShapes; 848 xSelectionSupplier->getSelection() >>= xShapes; 849 if (xShapes.is()) 850 xShapes->remove(xShape); 851 852 try 853 { 854 xSelectionSupplier->select(uno::makeAny(xShapes)); 855 } 856 catch (lang::IllegalArgumentException&) 857 { 858 DBG_ERRORFILE("something not selectable"); 859 } 860 861 maZOrderedShapes[nChildIndex]->bSelected = sal_False; 862 if (maZOrderedShapes[nChildIndex]->pAccShape) 863 maZOrderedShapes[nChildIndex]->pAccShape->ResetState(AccessibleStateType::SELECTED); 864 } 865 } 866 } 867 868 869 SdrPage* ScChildrenShapes::GetDrawPage() const 870 { 871 SCTAB nTab(mpAccessibleDocument->getVisibleTable()); 872 SdrPage* pDrawPage = NULL; 873 if (mpViewShell) 874 { 875 ScDocument* pDoc = mpViewShell->GetViewData()->GetDocument(); 876 if (pDoc && pDoc->GetDrawLayer()) 877 { 878 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); 879 if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab)) 880 pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab))); 881 } 882 } 883 return pDrawPage; 884 } 885 886 struct SetRelation 887 { 888 const ScChildrenShapes* mpChildrenShapes; 889 mutable utl::AccessibleRelationSetHelper* mpRelationSet; 890 const ScAddress* mpAddress; 891 SetRelation(const ScChildrenShapes* pChildrenShapes, const ScAddress* pAddress) 892 : 893 mpChildrenShapes(pChildrenShapes), 894 mpRelationSet(NULL), 895 mpAddress(pAddress) 896 { 897 } 898 void operator() (const ScAccessibleShapeData* pAccShapeData) const 899 { 900 if (pAccShapeData && 901 ((!pAccShapeData->pRelationCell && !mpAddress) || 902 (pAccShapeData->pRelationCell && mpAddress && (*(pAccShapeData->pRelationCell) == *mpAddress)))) 903 { 904 if (!mpRelationSet) 905 mpRelationSet = new utl::AccessibleRelationSetHelper(); 906 907 AccessibleRelation aRelation; 908 aRelation.TargetSet.realloc(1); 909 aRelation.TargetSet[0] = mpChildrenShapes->Get(pAccShapeData); 910 aRelation.RelationType = AccessibleRelationType::CONTROLLER_FOR; 911 912 mpRelationSet->AddRelation(aRelation); 913 } 914 } 915 }; 916 917 utl::AccessibleRelationSetHelper* ScChildrenShapes::GetRelationSet(const ScAddress* pAddress) const 918 { 919 SetRelation aSetRelation(this, pAddress); 920 ::std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), aSetRelation); 921 return aSetRelation.mpRelationSet; 922 } 923 924 sal_Bool ScChildrenShapes::FindSelectedShapesChanges(const uno::Reference<drawing::XShapes>& xShapes, sal_Bool /* bCommitChange */) const 925 { 926 sal_Bool bResult(sal_False); 927 SortedShapes aShapesList; 928 uno::Reference<container::XIndexAccess> xIndexAcc(xShapes, uno::UNO_QUERY); 929 if (xIndexAcc.is()) 930 { 931 mnShapesSelected = xIndexAcc->getCount(); 932 for (sal_uInt32 i = 0; i < mnShapesSelected; ++i) 933 { 934 uno::Reference< drawing::XShape > xShape; 935 xIndexAcc->getByIndex(i) >>= xShape; 936 if (xShape.is()) 937 { 938 ScAccessibleShapeData* pShapeData = new ScAccessibleShapeData(); 939 pShapeData->xShape = xShape; 940 aShapesList.push_back(pShapeData); 941 } 942 } 943 } 944 else 945 mnShapesSelected = 0; 946 SdrObject *pFocusedObj = NULL; 947 if( mnShapesSelected == 1 && aShapesList.size() == 1) 948 { 949 pFocusedObj = GetSdrObjectFromXShape(aShapesList[0]->xShape); 950 } 951 ScShapeDataLess aLess; 952 std::sort(aShapesList.begin(), aShapesList.end(), aLess); 953 SortedShapes vecSelectedShapeAdd; 954 SortedShapes vecSelectedShapeRemove; 955 sal_Bool bHasSelect=sal_False; 956 SortedShapes::iterator aXShapesItr(aShapesList.begin()); 957 SortedShapes::const_iterator aXShapesEndItr(aShapesList.end()); 958 SortedShapes::iterator aDataItr(maZOrderedShapes.begin()); 959 SortedShapes::const_iterator aDataEndItr(maZOrderedShapes.end()); 960 SortedShapes::const_iterator aFocusedItr = aDataEndItr; 961 while((aDataItr != aDataEndItr)) 962 { 963 if (*aDataItr) // is it realy a shape or only the sheet 964 { 965 sal_Int8 nComp(0); 966 if (aXShapesItr == aXShapesEndItr) 967 nComp = -1; // simulate that the Shape is lower, so the selction state will be removed 968 else 969 nComp = Compare(*aDataItr, *aXShapesItr); 970 if (nComp == 0) 971 { 972 if (!(*aDataItr)->bSelected) 973 { 974 (*aDataItr)->bSelected = sal_True; 975 if ((*aDataItr)->pAccShape) 976 { 977 (*aDataItr)->pAccShape->SetState(AccessibleStateType::SELECTED); 978 (*aDataItr)->pAccShape->ResetState(AccessibleStateType::FOCUSED); 979 bResult = sal_True; 980 vecSelectedShapeAdd.push_back((*aDataItr)); 981 } 982 aFocusedItr = aDataItr; 983 } 984 else 985 { 986 bHasSelect = sal_True; 987 } 988 ++aDataItr; 989 ++aXShapesItr; 990 } 991 else if (nComp < 0) 992 { 993 if ((*aDataItr)->bSelected) 994 { 995 (*aDataItr)->bSelected = sal_False; 996 if ((*aDataItr)->pAccShape) 997 { 998 (*aDataItr)->pAccShape->ResetState(AccessibleStateType::SELECTED); 999 (*aDataItr)->pAccShape->ResetState(AccessibleStateType::FOCUSED); 1000 bResult = sal_True; 1001 vecSelectedShapeRemove.push_back(*aDataItr); 1002 } 1003 } 1004 ++aDataItr; 1005 } 1006 else 1007 { 1008 DBG_ERRORFILE("here is a selected shape which is not in the childlist"); 1009 ++aXShapesItr; 1010 --mnShapesSelected; 1011 } 1012 } 1013 else 1014 ++aDataItr; 1015 } 1016 bool bWinFocus=false; 1017 if (mpViewShell) 1018 { 1019 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 1020 if (pWin) 1021 { 1022 bWinFocus = pWin->HasFocus(); 1023 } 1024 } 1025 const SdrMarkList* pMarkList = NULL; 1026 SdrObject* pMarkedObj = NULL; 1027 SdrObject* pUpObj = NULL; 1028 sal_Bool bIsFocuseMarked = sal_True; 1029 if( mpViewShell && mnShapesSelected == 1 && bWinFocus) 1030 { 1031 ScDrawView* pScDrawView = mpViewShell->GetViewData()->GetScDrawView(); 1032 if( pScDrawView ) 1033 { 1034 if( pScDrawView->GetMarkedObjectList().GetMarkCount() == 1 ) 1035 { 1036 pMarkList = &(pScDrawView->GetMarkedObjectList()); 1037 pMarkedObj = pMarkList->GetMark(0)->GetMarkedSdrObj(); 1038 uno::Reference< drawing::XShape > xMarkedXShape (pMarkedObj->getUnoShape(), uno::UNO_QUERY); 1039 if( aFocusedItr != aDataEndItr && 1040 (*aFocusedItr)->xShape.is() && 1041 xMarkedXShape.is() && 1042 (*aFocusedItr)->xShape != xMarkedXShape ) 1043 bIsFocuseMarked = sal_False; 1044 } 1045 } 1046 } 1047 //if ((aFocusedItr != aDataEndItr) && (*aFocusedItr)->pAccShape && (mnShapesSelected == 1)) 1048 if ( bIsFocuseMarked && (aFocusedItr != aDataEndItr) && (*aFocusedItr)->pAccShape && (mnShapesSelected == 1) && bWinFocus) 1049 { 1050 (*aFocusedItr)->pAccShape->SetState(AccessibleStateType::FOCUSED); 1051 } 1052 else if( pFocusedObj && bWinFocus && pMarkList && pMarkList->GetMarkCount() == 1 && mnShapesSelected == 1 ) 1053 { 1054 if( pMarkedObj ) 1055 { 1056 uno::Reference< drawing::XShape > xMarkedXShape (pMarkedObj->getUnoShape(), uno::UNO_QUERY); 1057 pUpObj = pMarkedObj->GetUpGroup(); 1058 1059 if( pMarkedObj == pFocusedObj ) 1060 { 1061 if( pUpObj ) 1062 { 1063 uno::Reference< drawing::XShape > xUpGroupXShape (pUpObj->getUnoShape(), uno::UNO_QUERY); 1064 uno::Reference < XAccessible > xAccGroupShape = 1065 const_cast<ScChildrenShapes*>(this)->GetAccessibleCaption( xUpGroupXShape ); 1066 if( xAccGroupShape.is() ) 1067 { 1068 ::accessibility::AccessibleShape* pAccGroupShape = 1069 static_cast< ::accessibility::AccessibleShape* >(xAccGroupShape.get()); 1070 if( pAccGroupShape ) 1071 { 1072 sal_Int32 nCount = pAccGroupShape->getAccessibleChildCount(); 1073 for( sal_Int32 i = 0; i < nCount; i++ ) 1074 { 1075 uno::Reference<XAccessible> xAccShape = pAccGroupShape->getAccessibleChild(i); 1076 if (xAccShape.is()) 1077 { 1078 ::accessibility::AccessibleShape* pChildAccShape = static_cast< ::accessibility::AccessibleShape* >(xAccShape.get()); 1079 uno::Reference< drawing::XShape > xChildShape = pChildAccShape->GetXShape(); 1080 if (xChildShape == xMarkedXShape) 1081 { 1082 pChildAccShape->SetState(AccessibleStateType::FOCUSED); 1083 } 1084 else 1085 { 1086 pChildAccShape->ResetState(AccessibleStateType::FOCUSED); 1087 } 1088 } 1089 } 1090 } 1091 } 1092 } 1093 } 1094 } 1095 } 1096 if (vecSelectedShapeAdd.size() >= 10 ) 1097 { 1098 AccessibleEventObject aEvent; 1099 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN; 1100 aEvent.Source = uno::Reference< XAccessible >(mpAccessibleDocument); 1101 mpAccessibleDocument->CommitChange(aEvent); 1102 } 1103 else 1104 { 1105 SortedShapes::iterator vi = vecSelectedShapeAdd.begin(); 1106 for (; vi != vecSelectedShapeAdd.end() ; ++vi ) 1107 { 1108 AccessibleEventObject aEvent; 1109 if (bHasSelect) 1110 { 1111 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_ADD; 1112 } 1113 else 1114 { 1115 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; 1116 } 1117 aEvent.Source = uno::Reference< XAccessible >(mpAccessibleDocument); 1118 uno::Reference< XAccessible > xChild( (*vi)->pAccShape); 1119 aEvent.NewValue <<= xChild; 1120 mpAccessibleDocument->CommitChange(aEvent); 1121 } 1122 } 1123 SortedShapes::iterator vi = vecSelectedShapeRemove.begin(); 1124 for (; vi != vecSelectedShapeRemove.end() ; ++vi ) 1125 { 1126 AccessibleEventObject aEvent; 1127 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE; 1128 aEvent.Source = uno::Reference< XAccessible >(mpAccessibleDocument); 1129 uno::Reference< XAccessible > xChild( (*vi)->pAccShape); 1130 aEvent.NewValue <<= xChild; 1131 mpAccessibleDocument->CommitChange(aEvent); 1132 } 1133 std::for_each(aShapesList.begin(), aShapesList.end(), Destroy()); 1134 1135 return bResult; 1136 } 1137 1138 void ScChildrenShapes::FillSelectionSupplier() const 1139 { 1140 if (!xSelectionSupplier.is() && mpViewShell) 1141 { 1142 SfxViewFrame* pViewFrame = mpViewShell->GetViewFrame(); 1143 if (pViewFrame) 1144 { 1145 xSelectionSupplier = uno::Reference<view::XSelectionSupplier>(pViewFrame->GetFrame().GetController(), uno::UNO_QUERY); 1146 if (xSelectionSupplier.is()) 1147 { 1148 if (mpAccessibleDocument) 1149 xSelectionSupplier->addSelectionChangeListener(mpAccessibleDocument); 1150 uno::Reference<drawing::XShapes> xShapes (xSelectionSupplier->getSelection(), uno::UNO_QUERY); 1151 if (xShapes.is()) 1152 mnShapesSelected = xShapes->getCount(); 1153 } 1154 } 1155 } 1156 } 1157 1158 ScAddress* ScChildrenShapes::GetAnchor(const uno::Reference<drawing::XShape>& xShape) const 1159 { 1160 ScAddress* pAddress = NULL; 1161 if (mpViewShell) 1162 { 1163 SvxShape* pShapeImp = SvxShape::getImplementation(xShape); 1164 uno::Reference<beans::XPropertySet> xShapeProp(xShape, uno::UNO_QUERY); 1165 if (pShapeImp && xShapeProp.is()) 1166 { 1167 SdrObject *pSdrObj = pShapeImp->GetSdrObject(); 1168 if (pSdrObj) 1169 { 1170 if (ScDrawLayer::GetAnchor(pSdrObj) == SCA_CELL) 1171 { 1172 ScDocument* pDoc = mpViewShell->GetViewData()->GetDocument(); 1173 if (pDoc) 1174 { 1175 rtl::OUString sCaptionShape(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CaptionShape")); 1176 awt::Point aPoint(xShape->getPosition()); 1177 awt::Size aSize(xShape->getSize()); 1178 rtl::OUString sType(xShape->getShapeType()); 1179 Rectangle aRectangle(aPoint.X, aPoint.Y, aPoint.X + aSize.Width, aPoint.Y + aSize.Height); 1180 if ( sType.equals(sCaptionShape) ) 1181 { 1182 awt::Point aRelativeCaptionPoint; 1183 rtl::OUString sCaptionPoint( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" )); 1184 xShapeProp->getPropertyValue( sCaptionPoint ) >>= aRelativeCaptionPoint; 1185 Point aCoreRelativeCaptionPoint(aRelativeCaptionPoint.X, aRelativeCaptionPoint.Y); 1186 Point aCoreAbsoluteCaptionPoint(aPoint.X, aPoint.Y); 1187 aCoreAbsoluteCaptionPoint += aCoreRelativeCaptionPoint; 1188 aRectangle.Union(Rectangle(aCoreAbsoluteCaptionPoint, aCoreAbsoluteCaptionPoint)); 1189 } 1190 ScRange aRange = pDoc->GetRange(mpAccessibleDocument->getVisibleTable(), aRectangle); 1191 pAddress = new ScAddress(aRange.aStart); 1192 } 1193 } 1194 // else 1195 // do nothing, because it is always a NULL Pointer 1196 } 1197 } 1198 } 1199 1200 return pAddress; 1201 } 1202 1203 uno::Reference<XAccessibleRelationSet> ScChildrenShapes::GetRelationSet(const ScAccessibleShapeData* pData) const 1204 { 1205 utl::AccessibleRelationSetHelper* pRelationSet = new utl::AccessibleRelationSetHelper(); 1206 1207 if(pData && pRelationSet && mpAccessibleDocument) 1208 { 1209 uno::Reference<XAccessible> xAccessible = mpAccessibleDocument->GetAccessibleSpreadsheet(); // should be the current table 1210 if (pData->pRelationCell && xAccessible.is()) 1211 { 1212 uno::Reference<XAccessibleTable> xAccTable (xAccessible->getAccessibleContext(), uno::UNO_QUERY); 1213 if (xAccTable.is()) 1214 xAccessible = xAccTable->getAccessibleCellAt(pData->pRelationCell->Row(), pData->pRelationCell->Col()); 1215 } 1216 AccessibleRelation aRelation; 1217 aRelation.TargetSet.realloc(1); 1218 aRelation.TargetSet[0] = xAccessible; 1219 aRelation.RelationType = AccessibleRelationType::CONTROLLED_BY; 1220 pRelationSet->AddRelation(aRelation); 1221 } 1222 1223 return pRelationSet; 1224 } 1225 1226 void ScChildrenShapes::CheckWhetherAnchorChanged(const uno::Reference<drawing::XShape>& xShape) const 1227 { 1228 SortedShapes::iterator aItr; 1229 if (FindShape(xShape, aItr)) 1230 SetAnchor(xShape, *aItr); 1231 } 1232 1233 void ScChildrenShapes::SetAnchor(const uno::Reference<drawing::XShape>& xShape, ScAccessibleShapeData* pData) const 1234 { 1235 if (pData) 1236 { 1237 ScAddress* pAddress = GetAnchor(xShape); 1238 if ((pAddress && pData->pRelationCell && (*pAddress != *(pData->pRelationCell))) || 1239 (!pAddress && pData->pRelationCell) || (pAddress && !pData->pRelationCell)) 1240 { 1241 if (pData->pRelationCell) 1242 delete pData->pRelationCell; 1243 pData->pRelationCell = pAddress; 1244 if (pData->pAccShape) 1245 pData->pAccShape->SetRelationSet(GetRelationSet(pData)); 1246 } 1247 } 1248 } 1249 1250 void ScChildrenShapes::AddShape(const uno::Reference<drawing::XShape>& xShape, sal_Bool bCommitChange) const 1251 { 1252 SortedShapes::iterator aFindItr; 1253 if (!FindShape(xShape, aFindItr)) 1254 { 1255 ScAccessibleShapeData* pShape = new ScAccessibleShapeData(); 1256 pShape->xShape = xShape; 1257 SortedShapes::iterator aNewItr = maZOrderedShapes.insert(aFindItr, pShape); 1258 SetAnchor(xShape, pShape); 1259 1260 uno::Reference< beans::XPropertySet > xShapeProp(xShape, uno::UNO_QUERY); 1261 if (xShapeProp.is()) 1262 { 1263 uno::Any aPropAny = xShapeProp->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "LayerID" ))); 1264 sal_Int16 nLayerID = 0; 1265 if( aPropAny >>= nLayerID ) 1266 { 1267 if( (nLayerID == SC_LAYER_INTERN) || (nLayerID == SC_LAYER_HIDDEN) ) 1268 pShape->bSelectable = sal_False; 1269 else 1270 pShape->bSelectable = sal_True; 1271 } 1272 } 1273 1274 1275 if (!xSelectionSupplier.is()) 1276 throw uno::RuntimeException(); 1277 1278 uno::Reference<container::XEnumerationAccess> xEnumAcc(xSelectionSupplier->getSelection(), uno::UNO_QUERY); 1279 if (xEnumAcc.is()) 1280 { 1281 uno::Reference<container::XEnumeration> xEnum = xEnumAcc->createEnumeration(); 1282 if (xEnum.is()) 1283 { 1284 uno::Reference<drawing::XShape> xSelectedShape; 1285 sal_Bool bFound(sal_False); 1286 while (!bFound && xEnum->hasMoreElements()) 1287 { 1288 xEnum->nextElement() >>= xSelectedShape; 1289 if (xShape.is() && (xShape.get() == xSelectedShape.get())) 1290 { 1291 pShape->bSelected = sal_True; 1292 bFound = sal_True; 1293 } 1294 } 1295 } 1296 } 1297 if (mpAccessibleDocument && bCommitChange) 1298 { 1299 AccessibleEventObject aEvent; 1300 aEvent.EventId = AccessibleEventId::CHILD; 1301 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument); 1302 aEvent.NewValue <<= Get(aNewItr - maZOrderedShapes.begin()); 1303 1304 mpAccessibleDocument->CommitChange(aEvent); // new child - event 1305 } 1306 } 1307 else 1308 { 1309 DBG_ERRORFILE("shape is always in the list"); 1310 } 1311 } 1312 1313 void ScChildrenShapes::RemoveShape(const uno::Reference<drawing::XShape>& xShape) const 1314 { 1315 SortedShapes::iterator aItr; 1316 if (FindShape(xShape, aItr)) 1317 { 1318 if (mpAccessibleDocument) 1319 { 1320 uno::Reference<XAccessible> xOldAccessible (Get(aItr - maZOrderedShapes.begin())); 1321 1322 delete *aItr; 1323 maZOrderedShapes.erase(aItr); 1324 1325 AccessibleEventObject aEvent; 1326 aEvent.EventId = AccessibleEventId::CHILD; 1327 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument); 1328 aEvent.OldValue <<= uno::makeAny(xOldAccessible); 1329 1330 mpAccessibleDocument->CommitChange(aEvent); // child is gone - event 1331 } 1332 else 1333 { 1334 delete *aItr; 1335 maZOrderedShapes.erase(aItr); 1336 } 1337 } 1338 else 1339 { 1340 DBG_ERRORFILE("shape was not in internal list"); 1341 } 1342 } 1343 1344 sal_Bool ScChildrenShapes::FindShape(const uno::Reference<drawing::XShape>& xShape, ScChildrenShapes::SortedShapes::iterator& rItr) const 1345 { 1346 sal_Bool bResult(sal_False); 1347 ScAccessibleShapeData aShape; 1348 aShape.xShape = xShape; 1349 ScShapeDataLess aLess; 1350 rItr = std::lower_bound(maZOrderedShapes.begin(), maZOrderedShapes.end(), &aShape, aLess); 1351 if ((rItr != maZOrderedShapes.end()) && (*rItr != NULL) && ((*rItr)->xShape.get() == xShape.get())) 1352 bResult = sal_True; // if the shape is found 1353 1354 #ifdef DBG_UTIL // test whether it finds truly the correct shape (perhaps it is not really sorted) 1355 SortedShapes::iterator aDebugItr = maZOrderedShapes.begin(); 1356 SortedShapes::iterator aEndItr = maZOrderedShapes.end(); 1357 sal_Bool bFound(sal_False); 1358 while (!bFound && aDebugItr != aEndItr) 1359 { 1360 if (*aDebugItr && ((*aDebugItr)->xShape.get() == xShape.get())) 1361 bFound = sal_True; 1362 else 1363 ++aDebugItr; 1364 } 1365 sal_Bool bResult2 = (aDebugItr != maZOrderedShapes.end()); 1366 DBG_ASSERT((bResult == bResult2) && ((bResult && (rItr == aDebugItr)) || !bResult), "wrong Shape found"); 1367 #endif 1368 return bResult; 1369 } 1370 1371 sal_Int8 ScChildrenShapes::Compare(const ScAccessibleShapeData* pData1, 1372 const ScAccessibleShapeData* pData2) const 1373 { 1374 ScShapeDataLess aLess; 1375 1376 sal_Bool bResult1(aLess(pData1, pData2)); 1377 sal_Bool bResult2(aLess(pData2, pData1)); 1378 1379 sal_Int8 nResult(0); 1380 if (!bResult1 && bResult2) 1381 nResult = 1; 1382 else if (bResult1 && !bResult2) 1383 nResult = -1; 1384 1385 return nResult; 1386 } 1387 1388 struct ScVisAreaChanged 1389 { 1390 ScAccessibleDocument* mpAccDoc; 1391 ScVisAreaChanged(ScAccessibleDocument* pAccDoc) : mpAccDoc(pAccDoc) {} 1392 void operator() (const ScAccessibleShapeData* pAccShapeData) const 1393 { 1394 if (pAccShapeData && pAccShapeData->pAccShape) 1395 { 1396 pAccShapeData->pAccShape->ViewForwarderChanged(::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA, mpAccDoc); 1397 } 1398 } 1399 }; 1400 1401 void ScChildrenShapes::VisAreaChanged() const 1402 { 1403 ScVisAreaChanged aVisAreaChanged(mpAccessibleDocument); 1404 std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), aVisAreaChanged); 1405 } 1406 1407 // ============================================================================ 1408 1409 ScAccessibleDocument::ScAccessibleDocument( 1410 const uno::Reference<XAccessible>& rxParent, 1411 ScTabViewShell* pViewShell, 1412 ScSplitPos eSplitPos) 1413 : ScAccessibleDocumentBase(rxParent), 1414 mpViewShell(pViewShell), 1415 meSplitPos(eSplitPos), 1416 mpAccessibleSpreadsheet(NULL), 1417 mpChildrenShapes(NULL), 1418 mpTempAccEdit(NULL), 1419 mbCompleteSheetSelected(sal_False) 1420 { 1421 if (pViewShell) 1422 { 1423 pViewShell->AddAccessibilityObject(*this); 1424 Window *pWin = pViewShell->GetWindowByPos(eSplitPos); 1425 if( pWin ) 1426 { 1427 pWin->AddChildEventListener( LINK( this, ScAccessibleDocument, WindowChildEventListener )); 1428 sal_uInt16 nCount = pWin->GetChildCount(); 1429 for( sal_uInt16 i=0; i < nCount; ++i ) 1430 { 1431 Window *pChildWin = pWin->GetChild( i ); 1432 if( pChildWin && 1433 AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() ) 1434 AddChild( pChildWin->GetAccessible(), sal_False ); 1435 } 1436 } 1437 if (pViewShell->GetViewData()->HasEditView( eSplitPos )) 1438 { 1439 uno::Reference<XAccessible> xAcc = new ScAccessibleEditObject(this, pViewShell->GetViewData()->GetEditView(eSplitPos), 1440 pViewShell->GetWindowByPos(eSplitPos), GetCurrentCellName(), GetCurrentCellDescription(), 1441 CellInEditMode); 1442 AddChild(xAcc, sal_False); 1443 } 1444 } 1445 maVisArea = GetVisibleArea_Impl(); 1446 } 1447 1448 void ScAccessibleDocument::Init() 1449 { 1450 if(!mpChildrenShapes) 1451 mpChildrenShapes = new ScChildrenShapes(this, mpViewShell, meSplitPos); 1452 } 1453 1454 ScAccessibleDocument::~ScAccessibleDocument(void) 1455 { 1456 if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose) 1457 { 1458 // increment refcount to prevent double call off dtor 1459 osl_incrementInterlockedCount( &m_refCount ); 1460 dispose(); 1461 } 1462 } 1463 1464 void SAL_CALL ScAccessibleDocument::disposing() 1465 { 1466 ScUnoGuard aGuard; 1467 FreeAccessibleSpreadsheet(); 1468 if (mpViewShell) 1469 { 1470 Window *pWin = mpViewShell->GetWindowByPos(meSplitPos); 1471 if( pWin ) 1472 pWin->RemoveChildEventListener( LINK( this, ScAccessibleDocument, WindowChildEventListener )); 1473 1474 mpViewShell->RemoveAccessibilityObject(*this); 1475 mpViewShell = NULL; 1476 } 1477 if (mpChildrenShapes) 1478 DELETEZ(mpChildrenShapes); 1479 1480 ScAccessibleDocumentBase::disposing(); 1481 } 1482 1483 void SAL_CALL ScAccessibleDocument::disposing( const lang::EventObject& /* Source */ ) 1484 throw (uno::RuntimeException) 1485 { 1486 disposing(); 1487 } 1488 1489 //===== SfxListener ===================================================== 1490 1491 IMPL_LINK( ScAccessibleDocument, WindowChildEventListener, VclSimpleEvent*, pEvent ) 1492 { 1493 DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" ); 1494 if ( pEvent && pEvent->ISA( VclWindowEvent ) ) 1495 { 1496 VclWindowEvent *pVclEvent = static_cast< VclWindowEvent * >( pEvent ); 1497 DBG_ASSERT( pVclEvent->GetWindow(), "Window???" ); 1498 switch ( pVclEvent->GetId() ) 1499 { 1500 case VCLEVENT_WINDOW_SHOW: // send create on show for direct accessible children 1501 { 1502 Window* pChildWin = static_cast < Window * >( pVclEvent->GetData() ); 1503 if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() ) 1504 { 1505 AddChild( pChildWin->GetAccessible(), sal_True ); 1506 } 1507 } 1508 break; 1509 case VCLEVENT_WINDOW_HIDE: // send destroy on hide for direct accessible children 1510 { 1511 Window* pChildWin = static_cast < Window * >( pVclEvent->GetData() ); 1512 if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() ) 1513 { 1514 RemoveChild( pChildWin->GetAccessible(), sal_True ); 1515 } 1516 } 1517 break; 1518 } 1519 } 1520 return 0; 1521 } 1522 1523 void ScAccessibleDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) 1524 { 1525 if (rHint.ISA( ScAccGridWinFocusLostHint ) ) 1526 { 1527 const ScAccGridWinFocusLostHint& rRef = (const ScAccGridWinFocusLostHint&)rHint; 1528 if (rRef.GetOldGridWin() == meSplitPos) 1529 { 1530 if (mxTempAcc.is() && mpTempAccEdit) 1531 mpTempAccEdit->LostFocus(); 1532 else if (mpAccessibleSpreadsheet) 1533 mpAccessibleSpreadsheet->LostFocus(); 1534 else 1535 CommitFocusLost(); 1536 } 1537 } 1538 else if (rHint.ISA( ScAccGridWinFocusGotHint ) ) 1539 { 1540 const ScAccGridWinFocusGotHint& rRef = (const ScAccGridWinFocusGotHint&)rHint; 1541 if (rRef.GetNewGridWin() == meSplitPos) 1542 { 1543 uno::Reference<XAccessible> xAccessible; 1544 if (mpChildrenShapes) 1545 { 1546 sal_Bool bTabMarked(IsTableSelected()); 1547 xAccessible = mpChildrenShapes->GetSelected(0, bTabMarked); 1548 } 1549 if( xAccessible.is() ) 1550 { 1551 uno::Any aNewValue; 1552 aNewValue<<=AccessibleStateType::FOCUSED; 1553 static_cast< ::accessibility::AccessibleShape* >(xAccessible.get())-> 1554 CommitChange(AccessibleEventId::STATE_CHANGED, 1555 aNewValue, 1556 uno::Any() ); 1557 } 1558 else 1559 { 1560 if (mxTempAcc.is() && mpTempAccEdit) 1561 mpTempAccEdit->GotFocus(); 1562 else if (mpAccessibleSpreadsheet) 1563 mpAccessibleSpreadsheet->GotFocus(); 1564 else 1565 CommitFocusGained(); 1566 } 1567 } 1568 } 1569 else if (rHint.ISA( SfxSimpleHint )) 1570 { 1571 const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint; 1572 // only notify if child exist, otherwise it is not necessary 1573 if ((rRef.GetId() == SC_HINT_ACC_TABLECHANGED) && 1574 mpAccessibleSpreadsheet) 1575 { 1576 FreeAccessibleSpreadsheet(); 1577 if (mpChildrenShapes) 1578 DELETEZ(mpChildrenShapes); 1579 1580 // #124567# Accessibility: Shapes / form controls after reload not accessible 1581 if ( !mpChildrenShapes ) 1582 { 1583 mpChildrenShapes = new ScChildrenShapes( this, mpViewShell, meSplitPos ); 1584 } 1585 //Invoke Init() to rebuild the mpChildrenShapes variable 1586 this->Init(); 1587 AccessibleEventObject aEvent; 1588 aEvent.EventId = AccessibleEventId::INVALIDATE_ALL_CHILDREN; 1589 aEvent.Source = uno::Reference< XAccessibleContext >(this); 1590 CommitChange(aEvent); // all childs changed 1591 if (mpAccessibleSpreadsheet) 1592 mpAccessibleSpreadsheet->FireFirstCellFocus(); 1593 } 1594 else if (rRef.GetId() == SC_HINT_ACC_MAKEDRAWLAYER) 1595 { 1596 if (mpChildrenShapes) 1597 mpChildrenShapes->SetDrawBroadcaster(); 1598 } 1599 else if ((rRef.GetId() == SC_HINT_ACC_ENTEREDITMODE)) // this event comes only on creating edit field of a cell 1600 { 1601 if (mpViewShell && mpViewShell->GetViewData()->HasEditView(meSplitPos)) 1602 { 1603 EditEngine* pEditEng = mpViewShell->GetViewData()->GetEditView(meSplitPos)->GetEditEngine(); 1604 if (pEditEng && pEditEng->GetUpdateMode()) 1605 { 1606 mpTempAccEdit = new ScAccessibleEditObject(this, mpViewShell->GetViewData()->GetEditView(meSplitPos), 1607 mpViewShell->GetWindowByPos(meSplitPos), GetCurrentCellName(), 1608 rtl::OUString(String(ScResId(STR_ACC_EDITLINE_DESCR))), CellInEditMode); 1609 uno::Reference<XAccessible> xAcc = mpTempAccEdit; 1610 1611 AddChild(xAcc, sal_True); 1612 1613 if (mpAccessibleSpreadsheet) 1614 mpAccessibleSpreadsheet->LostFocus(); 1615 else 1616 CommitFocusLost(); 1617 1618 mpTempAccEdit->GotFocus(); 1619 } 1620 } 1621 } 1622 else if (rRef.GetId() == SC_HINT_ACC_LEAVEEDITMODE) 1623 { 1624 if (mxTempAcc.is()) 1625 { 1626 if (mpTempAccEdit) 1627 mpTempAccEdit->LostFocus(); 1628 1629 mpTempAccEdit = NULL; 1630 RemoveChild(mxTempAcc, sal_True); 1631 if (mpAccessibleSpreadsheet && mpViewShell->IsActive()) 1632 mpAccessibleSpreadsheet->GotFocus(); 1633 else if( mpViewShell->IsActive()) 1634 CommitFocusGained(); 1635 } 1636 } 1637 else if ((rRef.GetId() == SC_HINT_ACC_VISAREACHANGED) || (rRef.GetId() == SC_HINT_ACC_WINDOWRESIZED)) 1638 { 1639 Rectangle aOldVisArea(maVisArea); 1640 maVisArea = GetVisibleArea_Impl(); 1641 1642 if (maVisArea != aOldVisArea) 1643 { 1644 if (maVisArea.GetSize() != aOldVisArea.GetSize()) 1645 { 1646 AccessibleEventObject aEvent; 1647 aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED; 1648 aEvent.Source = uno::Reference< XAccessibleContext >(this); 1649 1650 CommitChange(aEvent); 1651 1652 if (mpAccessibleSpreadsheet) 1653 mpAccessibleSpreadsheet->BoundingBoxChanged(); 1654 if (mpAccessibleSpreadsheet && mpViewShell->IsActive()) 1655 mpAccessibleSpreadsheet->FireFirstCellFocus(); 1656 } 1657 else if (mpAccessibleSpreadsheet) 1658 { 1659 mpAccessibleSpreadsheet->VisAreaChanged(); 1660 } 1661 if (mpChildrenShapes) 1662 mpChildrenShapes->VisAreaChanged(); 1663 } 1664 } 1665 } 1666 1667 ScAccessibleDocumentBase::Notify(rBC, rHint); 1668 } 1669 1670 void SAL_CALL ScAccessibleDocument::selectionChanged( const lang::EventObject& /* aEvent */ ) 1671 throw (uno::RuntimeException) 1672 { 1673 sal_Bool bSelectionChanged(sal_False); 1674 if (mpAccessibleSpreadsheet) 1675 { 1676 sal_Bool bOldSelected(mbCompleteSheetSelected); 1677 mbCompleteSheetSelected = IsTableSelected(); 1678 if (bOldSelected != mbCompleteSheetSelected) 1679 { 1680 mpAccessibleSpreadsheet->CompleteSelectionChanged(mbCompleteSheetSelected); 1681 bSelectionChanged = sal_True; 1682 } 1683 } 1684 1685 if (mpChildrenShapes && mpChildrenShapes->SelectionChanged()) 1686 bSelectionChanged = sal_True; 1687 1688 if (bSelectionChanged) 1689 { 1690 AccessibleEventObject aEvent; 1691 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; 1692 aEvent.Source = uno::Reference< XAccessibleContext >(this); 1693 1694 CommitChange(aEvent); 1695 } 1696 if(mpChildrenShapes ) 1697 { 1698 mpChildrenShapes->SelectionChanged(); 1699 } 1700 } 1701 1702 //===== XInterface ===================================================== 1703 1704 uno::Any SAL_CALL ScAccessibleDocument::queryInterface( uno::Type const & rType ) 1705 throw (uno::RuntimeException) 1706 { 1707 uno::Any aAnyTmp; 1708 if(rType == ::getCppuType((com::sun::star::uno::Reference<XAccessibleGetAccFlowTo> *)NULL) ) 1709 { 1710 com::sun::star::uno::Reference<XAccessibleGetAccFlowTo> AccFromXShape = this; 1711 aAnyTmp <<= AccFromXShape; 1712 return aAnyTmp; 1713 } 1714 uno::Any aAny (ScAccessibleDocumentImpl::queryInterface(rType)); 1715 return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType); 1716 } 1717 1718 void SAL_CALL ScAccessibleDocument::acquire() 1719 throw () 1720 { 1721 ScAccessibleContextBase::acquire(); 1722 } 1723 1724 void SAL_CALL ScAccessibleDocument::release() 1725 throw () 1726 { 1727 ScAccessibleContextBase::release(); 1728 } 1729 1730 //===== XAccessibleComponent ============================================ 1731 1732 uno::Reference< XAccessible > SAL_CALL ScAccessibleDocument::getAccessibleAtPoint( 1733 const awt::Point& rPoint ) 1734 throw (uno::RuntimeException) 1735 { 1736 uno::Reference<XAccessible> xAccessible = NULL; 1737 if (containsPoint(rPoint)) 1738 { 1739 ScUnoGuard aGuard; 1740 IsObjectValid(); 1741 if (mpChildrenShapes) 1742 xAccessible = mpChildrenShapes->GetAt(rPoint); 1743 if(!xAccessible.is()) 1744 { 1745 if (mxTempAcc.is()) 1746 { 1747 uno::Reference< XAccessibleContext > xCont(mxTempAcc->getAccessibleContext()); 1748 uno::Reference< XAccessibleComponent > xComp(xCont, uno::UNO_QUERY); 1749 if (xComp.is()) 1750 { 1751 Rectangle aBound(VCLRectangle(xComp->getBounds())); 1752 if (aBound.IsInside(VCLPoint(rPoint))) 1753 xAccessible = mxTempAcc; 1754 } 1755 } 1756 if (!xAccessible.is()) 1757 xAccessible = GetAccessibleSpreadsheet(); 1758 } 1759 } 1760 return xAccessible; 1761 } 1762 1763 void SAL_CALL ScAccessibleDocument::grabFocus( ) 1764 throw (uno::RuntimeException) 1765 { 1766 ScUnoGuard aGuard; 1767 IsObjectValid(); 1768 if (getAccessibleParent().is()) 1769 { 1770 uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY); 1771 if (xAccessibleComponent.is()) 1772 { 1773 xAccessibleComponent->grabFocus(); 1774 // grab only focus if it does not have the focus and it is not hidden 1775 if (mpViewShell && mpViewShell->GetViewData() && 1776 (mpViewShell->GetViewData()->GetActivePart() != meSplitPos) && 1777 mpViewShell->GetWindowByPos(meSplitPos)->IsVisible()) 1778 { 1779 mpViewShell->ActivatePart(meSplitPos); 1780 } 1781 } 1782 } 1783 } 1784 1785 //===== XAccessibleContext ============================================== 1786 1787 /// Return the number of currently visible children. 1788 sal_Int32 SAL_CALL 1789 ScAccessibleDocument::getAccessibleChildCount(void) 1790 throw (uno::RuntimeException) 1791 { 1792 ScUnoGuard aGuard; 1793 IsObjectValid(); 1794 sal_Int32 nCount(1); 1795 if (mpChildrenShapes) 1796 nCount = mpChildrenShapes->GetCount(); // returns the count of the shapes inclusive the table 1797 1798 if (mxTempAcc.is()) 1799 ++nCount; 1800 1801 return nCount; 1802 } 1803 1804 /// Return the specified child or NULL if index is invalid. 1805 uno::Reference<XAccessible> SAL_CALL 1806 ScAccessibleDocument::getAccessibleChild(sal_Int32 nIndex) 1807 throw (uno::RuntimeException, 1808 lang::IndexOutOfBoundsException) 1809 { 1810 ScUnoGuard aGuard; 1811 IsObjectValid(); 1812 uno::Reference<XAccessible> xAccessible; 1813 if (nIndex >= 0) 1814 { 1815 sal_Int32 nCount(1); 1816 if (mpChildrenShapes) 1817 { 1818 xAccessible = mpChildrenShapes->Get(nIndex); // returns NULL if it is the table or out of range 1819 nCount = mpChildrenShapes->GetCount(); //there is always a table 1820 } 1821 if (!xAccessible.is()) 1822 { 1823 if (nIndex < nCount) 1824 xAccessible = GetAccessibleSpreadsheet(); 1825 else if (nIndex == nCount && mxTempAcc.is()) 1826 xAccessible = mxTempAcc; 1827 } 1828 } 1829 1830 if (!xAccessible.is()) 1831 throw lang::IndexOutOfBoundsException(); 1832 1833 return xAccessible; 1834 } 1835 1836 /// Return the set of current states. 1837 uno::Reference<XAccessibleStateSet> SAL_CALL 1838 ScAccessibleDocument::getAccessibleStateSet(void) 1839 throw (uno::RuntimeException) 1840 { 1841 ScUnoGuard aGuard; 1842 uno::Reference<XAccessibleStateSet> xParentStates; 1843 if (getAccessibleParent().is()) 1844 { 1845 uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext(); 1846 xParentStates = xParentContext->getAccessibleStateSet(); 1847 } 1848 utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper(); 1849 if (IsDefunc(xParentStates)) 1850 pStateSet->AddState(AccessibleStateType::DEFUNC); 1851 else 1852 { 1853 if (IsEditable(xParentStates)) 1854 pStateSet->AddState(AccessibleStateType::EDITABLE); 1855 pStateSet->AddState(AccessibleStateType::ENABLED); 1856 pStateSet->AddState(AccessibleStateType::OPAQUE); 1857 if (isShowing()) 1858 pStateSet->AddState(AccessibleStateType::SHOWING); 1859 if (isVisible()) 1860 pStateSet->AddState(AccessibleStateType::VISIBLE); 1861 } 1862 return pStateSet; 1863 } 1864 1865 ::rtl::OUString SAL_CALL 1866 ScAccessibleDocument::getAccessibleName(void) 1867 throw (::com::sun::star::uno::RuntimeException) 1868 { 1869 rtl::OUString sName = String(ScResId(STR_ACC_DOC_SPREADSHEET)); 1870 ScDocument* pScDoc = GetDocument(); 1871 if ( pScDoc ) 1872 { 1873 rtl::OUString sFileName = pScDoc->getDocAccTitle(); 1874 if ( !sFileName.getLength() ) 1875 { 1876 SfxObjectShell* pObjSh = pScDoc->GetDocumentShell(); 1877 if ( pObjSh ) 1878 { 1879 sFileName = pObjSh->GetTitle( SFX_TITLE_APINAME ); 1880 } 1881 } 1882 rtl::OUString sReadOnly; 1883 if (pScDoc->getDocReadOnly()) 1884 { 1885 sReadOnly = String(ScResId(STR_ACC_DOC_SPREADSHEET_READONLY)); 1886 } 1887 if ( sFileName.getLength() ) 1888 { 1889 sName = sFileName + sReadOnly + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" - ")) + sName; 1890 } 1891 } 1892 return sName; 1893 } 1894 ///===== XAccessibleSelection =========================================== 1895 1896 void SAL_CALL 1897 ScAccessibleDocument::selectAccessibleChild( sal_Int32 nChildIndex ) 1898 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1899 { 1900 ScUnoGuard aGuard; 1901 IsObjectValid(); 1902 1903 if (mpChildrenShapes) 1904 { 1905 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table 1906 if (mxTempAcc.is()) 1907 ++nCount; 1908 if (nChildIndex < 0 || nChildIndex >= nCount) 1909 throw lang::IndexOutOfBoundsException(); 1910 1911 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex); 1912 if (xAccessible.is()) 1913 { 1914 sal_Bool bWasTableSelected(IsTableSelected()); 1915 1916 if (mpChildrenShapes) 1917 mpChildrenShapes->Select(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high 1918 1919 if (bWasTableSelected) 1920 mpViewShell->SelectAll(); 1921 } 1922 else 1923 { 1924 if (mpViewShell) 1925 mpViewShell->SelectAll(); 1926 } 1927 } 1928 } 1929 1930 sal_Bool SAL_CALL 1931 ScAccessibleDocument::isAccessibleChildSelected( sal_Int32 nChildIndex ) 1932 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1933 { 1934 ScUnoGuard aGuard; 1935 IsObjectValid(); 1936 sal_Bool bResult(sal_False); 1937 1938 if (mpChildrenShapes) 1939 { 1940 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table 1941 if (mxTempAcc.is()) 1942 ++nCount; 1943 if (nChildIndex < 0 || nChildIndex >= nCount) 1944 throw lang::IndexOutOfBoundsException(); 1945 1946 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex); 1947 if (xAccessible.is()) 1948 { 1949 uno::Reference<drawing::XShape> xShape; 1950 bResult = mpChildrenShapes->IsSelected(nChildIndex, xShape); // throws no lang::IndexOutOfBoundsException if Index is to high 1951 } 1952 else 1953 { 1954 if (mxTempAcc.is() && nChildIndex == nCount) 1955 bResult = sal_True; 1956 else 1957 bResult = IsTableSelected(); 1958 } 1959 } 1960 return bResult; 1961 } 1962 1963 void SAL_CALL 1964 ScAccessibleDocument::clearAccessibleSelection( ) 1965 throw (uno::RuntimeException) 1966 { 1967 ScUnoGuard aGuard; 1968 IsObjectValid(); 1969 1970 if (mpChildrenShapes) 1971 mpChildrenShapes->DeselectAll(); //deselects all (also the table) 1972 } 1973 1974 void SAL_CALL 1975 ScAccessibleDocument::selectAllAccessibleChildren( ) 1976 throw (uno::RuntimeException) 1977 { 1978 ScUnoGuard aGuard; 1979 IsObjectValid(); 1980 1981 if (mpChildrenShapes) 1982 mpChildrenShapes->SelectAll(); 1983 1984 // select table after shapes, because while selecting shapes the table will be deselected 1985 if (mpViewShell) 1986 { 1987 mpViewShell->SelectAll(); 1988 } 1989 } 1990 1991 sal_Int32 SAL_CALL 1992 ScAccessibleDocument::getSelectedAccessibleChildCount( ) 1993 throw (uno::RuntimeException) 1994 { 1995 ScUnoGuard aGuard; 1996 IsObjectValid(); 1997 sal_Int32 nCount(0); 1998 1999 if (mpChildrenShapes) 2000 nCount = mpChildrenShapes->GetSelectedCount(); 2001 2002 if (IsTableSelected()) 2003 ++nCount; 2004 2005 if (mxTempAcc.is()) 2006 ++nCount; 2007 2008 return nCount; 2009 } 2010 2011 uno::Reference<XAccessible > SAL_CALL 2012 ScAccessibleDocument::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) 2013 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2014 { 2015 ScUnoGuard aGuard; 2016 IsObjectValid(); 2017 uno::Reference<XAccessible> xAccessible; 2018 if (mpChildrenShapes) 2019 { 2020 sal_Int32 nCount(getSelectedAccessibleChildCount()); //all shapes and the table 2021 if (nSelectedChildIndex < 0 || nSelectedChildIndex >= nCount) 2022 throw lang::IndexOutOfBoundsException(); 2023 2024 sal_Bool bTabMarked(IsTableSelected()); 2025 2026 if (mpChildrenShapes) 2027 xAccessible = mpChildrenShapes->GetSelected(nSelectedChildIndex, bTabMarked); // throws no lang::IndexOutOfBoundsException if Index is to high 2028 if (mxTempAcc.is() && nSelectedChildIndex == nCount - 1) 2029 xAccessible = mxTempAcc; 2030 else if (bTabMarked) 2031 xAccessible = GetAccessibleSpreadsheet(); 2032 } 2033 2034 DBG_ASSERT(xAccessible.is(), "here should always be an accessible object or a exception throwed"); 2035 2036 return xAccessible; 2037 } 2038 2039 void SAL_CALL 2040 ScAccessibleDocument::deselectAccessibleChild( sal_Int32 nChildIndex ) 2041 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2042 { 2043 ScUnoGuard aGuard; 2044 IsObjectValid(); 2045 2046 if (mpChildrenShapes) 2047 { 2048 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table 2049 if (mxTempAcc.is()) 2050 ++nCount; 2051 if (nChildIndex < 0 || nChildIndex >= nCount) 2052 throw lang::IndexOutOfBoundsException(); 2053 2054 sal_Bool bTabMarked(IsTableSelected()); 2055 2056 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex); 2057 if (xAccessible.is()) 2058 { 2059 if (mpChildrenShapes) 2060 mpChildrenShapes->Deselect(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high 2061 2062 if (bTabMarked) 2063 mpViewShell->SelectAll(); // select the table again 2064 } 2065 else if (bTabMarked) 2066 mpViewShell->Unmark(); 2067 } 2068 } 2069 2070 //===== XServiceInfo ==================================================== 2071 2072 ::rtl::OUString SAL_CALL 2073 ScAccessibleDocument::getImplementationName(void) 2074 throw (uno::RuntimeException) 2075 { 2076 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDocument")); 2077 } 2078 2079 uno::Sequence< ::rtl::OUString> SAL_CALL 2080 ScAccessibleDocument::getSupportedServiceNames(void) 2081 throw (uno::RuntimeException) 2082 { 2083 uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames(); 2084 sal_Int32 nOldSize(aSequence.getLength()); 2085 aSequence.realloc(nOldSize + 1); 2086 ::rtl::OUString* pNames = aSequence.getArray(); 2087 2088 pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheetDocumentView")); 2089 2090 return aSequence; 2091 } 2092 2093 //===== XTypeProvider ======================================================= 2094 2095 uno::Sequence< uno::Type > SAL_CALL ScAccessibleDocument::getTypes() 2096 throw (uno::RuntimeException) 2097 { 2098 return comphelper::concatSequences(ScAccessibleDocumentImpl::getTypes(), ScAccessibleContextBase::getTypes()); 2099 } 2100 2101 uno::Sequence<sal_Int8> SAL_CALL 2102 ScAccessibleDocument::getImplementationId(void) 2103 throw (uno::RuntimeException) 2104 { 2105 ScUnoGuard aGuard; 2106 IsObjectValid(); 2107 static uno::Sequence<sal_Int8> aId; 2108 if (aId.getLength() == 0) 2109 { 2110 aId.realloc (16); 2111 rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True); 2112 } 2113 return aId; 2114 } 2115 2116 ///===== IAccessibleViewForwarder ======================================== 2117 2118 sal_Bool ScAccessibleDocument::IsValid (void) const 2119 { 2120 ScUnoGuard aGuard; 2121 IsObjectValid(); 2122 return (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose); 2123 } 2124 2125 Rectangle ScAccessibleDocument::GetVisibleArea_Impl() const 2126 { 2127 Rectangle aVisRect(GetBoundingBox()); 2128 2129 Point aPoint(mpViewShell->GetViewData()->GetPixPos(meSplitPos)); // returns a negative Point 2130 aPoint.setX(-aPoint.getX()); 2131 aPoint.setY(-aPoint.getY()); 2132 aVisRect.SetPos(aPoint); 2133 2134 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 2135 if (pWin) 2136 aVisRect = pWin->PixelToLogic(aVisRect, pWin->GetDrawMapMode()); 2137 2138 return aVisRect; 2139 } 2140 2141 Rectangle ScAccessibleDocument::GetVisibleArea() const 2142 { 2143 ScUnoGuard aGuard; 2144 IsObjectValid(); 2145 return maVisArea; 2146 } 2147 2148 Point ScAccessibleDocument::LogicToPixel (const Point& rPoint) const 2149 { 2150 ScUnoGuard aGuard; 2151 IsObjectValid(); 2152 Point aPoint; 2153 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 2154 if (pWin) 2155 { 2156 aPoint = pWin->LogicToPixel(rPoint, pWin->GetDrawMapMode()); 2157 aPoint += pWin->GetWindowExtentsRelative(NULL).TopLeft(); 2158 } 2159 return aPoint; 2160 } 2161 2162 Size ScAccessibleDocument::LogicToPixel (const Size& rSize) const 2163 { 2164 ScUnoGuard aGuard; 2165 IsObjectValid(); 2166 Size aSize; 2167 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 2168 if (pWin) 2169 aSize = pWin->LogicToPixel(rSize, pWin->GetDrawMapMode()); 2170 return aSize; 2171 } 2172 2173 Point ScAccessibleDocument::PixelToLogic (const Point& rPoint) const 2174 { 2175 ScUnoGuard aGuard; 2176 IsObjectValid(); 2177 Point aPoint; 2178 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 2179 if (pWin) 2180 { 2181 aPoint -= pWin->GetWindowExtentsRelative(NULL).TopLeft(); 2182 aPoint = pWin->PixelToLogic(rPoint, pWin->GetDrawMapMode()); 2183 } 2184 return aPoint; 2185 } 2186 2187 Size ScAccessibleDocument::PixelToLogic (const Size& rSize) const 2188 { 2189 ScUnoGuard aGuard; 2190 IsObjectValid(); 2191 Size aSize; 2192 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 2193 if (pWin) 2194 aSize = pWin->PixelToLogic(rSize, pWin->GetDrawMapMode()); 2195 return aSize; 2196 } 2197 2198 //===== internal ======================================================== 2199 2200 utl::AccessibleRelationSetHelper* ScAccessibleDocument::GetRelationSet(const ScAddress* pAddress) const 2201 { 2202 utl::AccessibleRelationSetHelper* pRelationSet = NULL; 2203 if (mpChildrenShapes) 2204 pRelationSet = mpChildrenShapes->GetRelationSet(pAddress); 2205 return pRelationSet; 2206 } 2207 2208 ::rtl::OUString SAL_CALL 2209 ScAccessibleDocument::createAccessibleDescription(void) 2210 throw (uno::RuntimeException) 2211 { 2212 rtl::OUString sDescription = String(ScResId(STR_ACC_DOC_DESCR)); 2213 return sDescription; 2214 } 2215 2216 ::rtl::OUString SAL_CALL 2217 ScAccessibleDocument::createAccessibleName(void) 2218 throw (uno::RuntimeException) 2219 { 2220 ScUnoGuard aGuard; 2221 IsObjectValid(); 2222 rtl::OUString sName = String(ScResId(STR_ACC_DOC_NAME)); 2223 sal_Int32 nNumber(sal_Int32(meSplitPos) + 1); 2224 sName += rtl::OUString::valueOf(nNumber); 2225 return sName; 2226 } 2227 2228 Rectangle ScAccessibleDocument::GetBoundingBoxOnScreen() const 2229 throw (uno::RuntimeException) 2230 { 2231 Rectangle aRect; 2232 if (mpViewShell) 2233 { 2234 Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos); 2235 if (pWindow) 2236 aRect = pWindow->GetWindowExtentsRelative(NULL); 2237 } 2238 return aRect; 2239 } 2240 2241 Rectangle ScAccessibleDocument::GetBoundingBox() const 2242 throw (uno::RuntimeException) 2243 { 2244 Rectangle aRect; 2245 if (mpViewShell) 2246 { 2247 Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos); 2248 if (pWindow) 2249 aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow()); 2250 } 2251 return aRect; 2252 } 2253 2254 SCTAB ScAccessibleDocument::getVisibleTable() const 2255 { 2256 SCTAB nVisibleTable(0); 2257 if (mpViewShell && mpViewShell->GetViewData()) 2258 nVisibleTable = mpViewShell->GetViewData()->GetTabNo(); 2259 return nVisibleTable; 2260 } 2261 2262 uno::Reference < XAccessible > 2263 ScAccessibleDocument::GetAccessibleSpreadsheet() 2264 { 2265 if (!mpAccessibleSpreadsheet && mpViewShell) 2266 { 2267 mpAccessibleSpreadsheet = new ScAccessibleSpreadsheet(this, mpViewShell, getVisibleTable(), meSplitPos); 2268 mpAccessibleSpreadsheet->acquire(); 2269 mpAccessibleSpreadsheet->Init(); 2270 mbCompleteSheetSelected = IsTableSelected(); 2271 } 2272 return mpAccessibleSpreadsheet; 2273 } 2274 2275 void ScAccessibleDocument::FreeAccessibleSpreadsheet() 2276 { 2277 if (mpAccessibleSpreadsheet) 2278 { 2279 mpAccessibleSpreadsheet->dispose(); 2280 mpAccessibleSpreadsheet->release(); 2281 mpAccessibleSpreadsheet = NULL; 2282 } 2283 } 2284 2285 sal_Bool ScAccessibleDocument::IsTableSelected() const 2286 { 2287 sal_Bool bResult (sal_False); 2288 if(mpViewShell) 2289 { 2290 SCTAB nTab(getVisibleTable()); 2291 //#103800#; use a copy of MarkData 2292 ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData()); 2293 aMarkData.MarkToMulti(); 2294 if (aMarkData.IsAllMarked(ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab)))) 2295 bResult = sal_True; 2296 } 2297 return bResult; 2298 } 2299 2300 sal_Bool ScAccessibleDocument::IsDefunc( 2301 const uno::Reference<XAccessibleStateSet>& rxParentStates) 2302 { 2303 return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() || 2304 (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC)); 2305 } 2306 2307 sal_Bool ScAccessibleDocument::IsEditable( 2308 const uno::Reference<XAccessibleStateSet>& /* rxParentStates */) 2309 { 2310 // what is with document protection or readonly documents? 2311 return sal_True; 2312 } 2313 2314 void ScAccessibleDocument::AddChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent) 2315 { 2316 DBG_ASSERT(!mxTempAcc.is(), "this object should be removed before"); 2317 if (xAcc.is()) 2318 { 2319 mxTempAcc = xAcc; 2320 if( bFireEvent ) 2321 { 2322 AccessibleEventObject aEvent; 2323 aEvent.Source = uno::Reference<XAccessibleContext>(this); 2324 aEvent.EventId = AccessibleEventId::CHILD; 2325 aEvent.NewValue <<= mxTempAcc; 2326 CommitChange( aEvent ); 2327 } 2328 } 2329 } 2330 2331 void ScAccessibleDocument::RemoveChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent) 2332 { 2333 DBG_ASSERT(mxTempAcc.is(), "this object should be added before"); 2334 if (xAcc.is()) 2335 { 2336 DBG_ASSERT(xAcc.get() == mxTempAcc.get(), "only the same object should be removed"); 2337 if( bFireEvent ) 2338 { 2339 AccessibleEventObject aEvent; 2340 aEvent.Source = uno::Reference<XAccessibleContext>(this); 2341 aEvent.EventId = AccessibleEventId::CHILD; 2342 aEvent.OldValue <<= mxTempAcc; 2343 CommitChange( aEvent ); 2344 } 2345 mxTempAcc = NULL; 2346 } 2347 } 2348 2349 rtl::OUString ScAccessibleDocument::GetCurrentCellName() const 2350 { 2351 String sName( ScResId(STR_ACC_CELL_NAME) ); 2352 if (mpViewShell) 2353 { 2354 String sAddress; 2355 // Document not needed, because only the cell address, but not the tablename is needed 2356 mpViewShell->GetViewData()->GetCurPos().Format( sAddress, SCA_VALID, NULL ); 2357 sName.SearchAndReplaceAscii("%1", sAddress); 2358 } 2359 return rtl::OUString(sName); 2360 } 2361 2362 rtl::OUString ScAccessibleDocument::GetCurrentCellDescription() const 2363 { 2364 return rtl::OUString(); 2365 } 2366 ScDocument *ScAccessibleDocument::GetDocument() const 2367 { 2368 return mpViewShell ? mpViewShell->GetViewData()->GetDocument() : NULL; 2369 } 2370 ScAddress ScAccessibleDocument::GetCurCellAddress() const 2371 { 2372 return mpViewShell ? mpViewShell->GetViewData()->GetCurPos() :ScAddress(); 2373 } 2374 uno::Any SAL_CALL ScAccessibleDocument::getExtendedAttributes() 2375 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 2376 { 2377 2378 uno::Any anyAtrribute; 2379 2380 rtl::OUString sName; 2381 rtl::OUString sValue; 2382 sal_uInt16 sheetIndex; 2383 String sSheetName; 2384 sheetIndex = getVisibleTable(); 2385 if(GetDocument()==NULL) 2386 return anyAtrribute; 2387 GetDocument()->GetName(sheetIndex,sSheetName); 2388 sName = rtl::OUString::createFromAscii("page-name:"); 2389 sValue = sName + sSheetName ; 2390 sName = rtl::OUString::createFromAscii(";page-number:"); 2391 sValue += sName; 2392 sValue += String::CreateFromInt32(sheetIndex+1) ; 2393 sName = rtl::OUString::createFromAscii(";total-pages:"); 2394 sValue += sName; 2395 sValue += String::CreateFromInt32(GetDocument()->GetTableCount()); 2396 sValue += rtl::OUString::createFromAscii(";"); 2397 anyAtrribute <<= sValue; 2398 return anyAtrribute; 2399 } 2400 com::sun::star::uno::Sequence< com::sun::star::uno::Any > ScAccessibleDocument::GetScAccFlowToSequence() 2401 { 2402 if ( getAccessibleChildCount() ) 2403 { 2404 uno::Reference < XAccessible > xSCTableAcc = getAccessibleChild( 0 ); // table 2405 if ( xSCTableAcc.is() ) 2406 { 2407 uno::Reference < XAccessibleSelection > xAccSelection( xSCTableAcc, uno::UNO_QUERY ); 2408 sal_Int32 nSelCount = xAccSelection->getSelectedAccessibleChildCount(); 2409 if( nSelCount ) 2410 { 2411 uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 ); // selected cell 2412 if ( xSel.is() ) 2413 { 2414 uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() ); 2415 if ( xSelContext.is() ) 2416 { 2417 if ( xSelContext->getAccessibleRole() == AccessibleRole::TABLE_CELL ) 2418 { 2419 sal_Int32 nParaCount = 0; 2420 uno::Sequence <uno::Any> aSequence(nSelCount); 2421 for ( sal_Int32 i = 0; i < nSelCount; i++ ) 2422 { 2423 xSel = xAccSelection->getSelectedAccessibleChild( i ) ; 2424 if ( xSel.is() ) 2425 { 2426 xSelContext = xSel->getAccessibleContext(); 2427 if ( xSelContext.is() ) 2428 { 2429 if ( xSelContext->getAccessibleRole() == AccessibleRole::TABLE_CELL ) 2430 { 2431 aSequence[nParaCount] = uno::makeAny( xSel ); 2432 nParaCount++; 2433 } 2434 } 2435 } 2436 } 2437 return aSequence; 2438 } 2439 } 2440 } 2441 } 2442 } 2443 } 2444 uno::Sequence <uno::Any> aEmpty; 2445 return aEmpty; 2446 } 2447 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > 2448 SAL_CALL ScAccessibleDocument::get_AccFlowTo(const ::com::sun::star::uno::Any& rAny, sal_Int32 nType) 2449 throw ( ::com::sun::star::uno::RuntimeException ) 2450 { 2451 const sal_Int32 SPELLCHECKFLOWTO = 1; 2452 const sal_Int32 FINDREPLACEFLOWTO = 2; 2453 if ( nType == SPELLCHECKFLOWTO ) 2454 { 2455 uno::Reference< ::com::sun::star::drawing::XShape > xShape; 2456 rAny >>= xShape; 2457 if ( xShape.is() ) 2458 { 2459 uno::Reference < XAccessible > xAcc = mpChildrenShapes->GetAccessibleCaption(xShape); 2460 uno::Reference < XAccessibleSelection > xAccSelection( xAcc, uno::UNO_QUERY ); 2461 if ( xAccSelection.is() ) 2462 { 2463 if ( xAccSelection->getSelectedAccessibleChildCount() ) 2464 { 2465 uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 ); 2466 if ( xSel.is() ) 2467 { 2468 uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() ); 2469 if ( xSelContext.is() ) 2470 { 2471 //if in sw we find the selected paragraph here 2472 if ( xSelContext->getAccessibleRole() == AccessibleRole::PARAGRAPH ) 2473 { 2474 uno::Sequence<uno::Any> aRet( 1 ); 2475 aRet[0] = uno::makeAny( xSel ); 2476 return aRet; 2477 } 2478 } 2479 } 2480 } 2481 } 2482 } 2483 else 2484 { 2485 if ( getSelectedAccessibleChildCount() ) 2486 { 2487 uno::Reference < XAccessible > xSel = getSelectedAccessibleChild( 0 ); 2488 if ( xSel.is() ) 2489 { 2490 uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() ); 2491 if ( xSelContext.is() ) 2492 { 2493 uno::Reference < XAccessibleSelection > xAccChildSelection( xSel, uno::UNO_QUERY ); 2494 if ( xAccChildSelection.is() ) 2495 { 2496 if ( xAccChildSelection->getSelectedAccessibleChildCount() ) 2497 { 2498 uno::Reference < XAccessible > xChildSel = xAccChildSelection->getSelectedAccessibleChild( 0 ); 2499 if ( xChildSel.is() ) 2500 { 2501 uno::Reference < ::com::sun::star::accessibility::XAccessibleContext > xChildSelContext( xChildSel->getAccessibleContext() ); 2502 if ( xChildSelContext.is() && 2503 xChildSelContext->getAccessibleRole() == ::com::sun::star::accessibility::AccessibleRole::PARAGRAPH ) 2504 { 2505 uno::Sequence<uno::Any> aRet( 1 ); 2506 aRet[0] = uno::makeAny( xChildSel ); 2507 return aRet; 2508 } 2509 } 2510 } 2511 } 2512 } 2513 } 2514 } 2515 } 2516 } 2517 else if ( nType == FINDREPLACEFLOWTO ) 2518 { 2519 sal_Bool bSuccess(sal_False); 2520 rAny >>= bSuccess; 2521 if ( bSuccess ) 2522 { 2523 uno::Sequence< uno::Any> aSeq = GetScAccFlowToSequence(); 2524 if ( aSeq.getLength() ) 2525 { 2526 return aSeq; 2527 } 2528 else if( mpAccessibleSpreadsheet ) 2529 { 2530 uno::Reference < XAccessible > xFindCellAcc = mpAccessibleSpreadsheet->GetActiveCell(); 2531 // add xFindCellAcc to the return the Sequence 2532 uno::Sequence< uno::Any> aSeq2(1); 2533 aSeq2[0] = uno::makeAny( xFindCellAcc ); 2534 return aSeq2; 2535 } 2536 } 2537 } 2538 uno::Sequence< uno::Any> aEmpty; 2539 return aEmpty; 2540 } 2541 void ScAccessibleDocument::SwitchViewFireFocus() 2542 { 2543 if (mpAccessibleSpreadsheet) 2544 { 2545 mpAccessibleSpreadsheet->FireFirstCellFocus(); 2546 } 2547 } 2548 2549 sal_Int32 SAL_CALL ScAccessibleDocument::getForeground( ) 2550 throw (uno::RuntimeException) 2551 { 2552 return COL_BLACK; 2553 } 2554 2555 sal_Int32 SAL_CALL ScAccessibleDocument::getBackground( ) 2556 throw (uno::RuntimeException) 2557 { 2558 ScUnoGuard aGuard; 2559 IsObjectValid(); 2560 return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor; 2561 } 2562 2563