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