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 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 1018 if (pWin) 1019 { 1020 bWinFocus = pWin->HasFocus(); 1021 } 1022 const SdrMarkList* pMarkList = NULL; 1023 SdrObject* pMarkedObj = NULL; 1024 SdrObject* pUpObj = NULL; 1025 sal_Bool bIsFocuseMarked = sal_True; 1026 if( mpViewShell && mnShapesSelected == 1 && bWinFocus) 1027 { 1028 ScDrawView* pScDrawView = mpViewShell->GetViewData()->GetScDrawView(); 1029 if( pScDrawView ) 1030 { 1031 if( pScDrawView->GetMarkedObjectList().GetMarkCount() == 1 ) 1032 { 1033 pMarkList = &(pScDrawView->GetMarkedObjectList()); 1034 pMarkedObj = pMarkList->GetMark(0)->GetMarkedSdrObj(); 1035 uno::Reference< drawing::XShape > xMarkedXShape (pMarkedObj->getUnoShape(), uno::UNO_QUERY); 1036 if( aFocusedItr != aDataEndItr && 1037 (*aFocusedItr)->xShape.is() && 1038 xMarkedXShape.is() && 1039 (*aFocusedItr)->xShape != xMarkedXShape ) 1040 bIsFocuseMarked = sal_False; 1041 } 1042 } 1043 } 1044 //if ((aFocusedItr != aDataEndItr) && (*aFocusedItr)->pAccShape && (mnShapesSelected == 1)) 1045 if ( bIsFocuseMarked && (aFocusedItr != aDataEndItr) && (*aFocusedItr)->pAccShape && (mnShapesSelected == 1) && bWinFocus) 1046 { 1047 (*aFocusedItr)->pAccShape->SetState(AccessibleStateType::FOCUSED); 1048 } 1049 else if( pFocusedObj && bWinFocus && pMarkList && pMarkList->GetMarkCount() == 1 && mnShapesSelected == 1 ) 1050 { 1051 if( pMarkedObj ) 1052 { 1053 uno::Reference< drawing::XShape > xMarkedXShape (pMarkedObj->getUnoShape(), uno::UNO_QUERY); 1054 pUpObj = pMarkedObj->GetUpGroup(); 1055 1056 if( pMarkedObj == pFocusedObj ) 1057 { 1058 if( pUpObj ) 1059 { 1060 uno::Reference< drawing::XShape > xUpGroupXShape (pUpObj->getUnoShape(), uno::UNO_QUERY); 1061 uno::Reference < XAccessible > xAccGroupShape = 1062 const_cast<ScChildrenShapes*>(this)->GetAccessibleCaption( xUpGroupXShape ); 1063 if( xAccGroupShape.is() ) 1064 { 1065 ::accessibility::AccessibleShape* pAccGroupShape = 1066 static_cast< ::accessibility::AccessibleShape* >(xAccGroupShape.get()); 1067 if( pAccGroupShape ) 1068 { 1069 sal_Int32 nCount = pAccGroupShape->getAccessibleChildCount(); 1070 for( sal_Int32 i = 0; i < nCount; i++ ) 1071 { 1072 uno::Reference<XAccessible> xAccShape = pAccGroupShape->getAccessibleChild(i); 1073 if (xAccShape.is()) 1074 { 1075 ::accessibility::AccessibleShape* pChildAccShape = static_cast< ::accessibility::AccessibleShape* >(xAccShape.get()); 1076 uno::Reference< drawing::XShape > xChildShape = pChildAccShape->GetXShape(); 1077 if (xChildShape == xMarkedXShape) 1078 { 1079 pChildAccShape->SetState(AccessibleStateType::FOCUSED); 1080 } 1081 else 1082 { 1083 pChildAccShape->ResetState(AccessibleStateType::FOCUSED); 1084 } 1085 } 1086 } 1087 } 1088 } 1089 } 1090 } 1091 } 1092 } 1093 if (vecSelectedShapeAdd.size() >= 10 ) 1094 { 1095 AccessibleEventObject aEvent; 1096 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN; 1097 aEvent.Source = uno::Reference< XAccessible >(mpAccessibleDocument); 1098 mpAccessibleDocument->CommitChange(aEvent); 1099 } 1100 else 1101 { 1102 SortedShapes::iterator vi = vecSelectedShapeAdd.begin(); 1103 for (; vi != vecSelectedShapeAdd.end() ; ++vi ) 1104 { 1105 AccessibleEventObject aEvent; 1106 if (bHasSelect) 1107 { 1108 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_ADD; 1109 } 1110 else 1111 { 1112 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; 1113 } 1114 aEvent.Source = uno::Reference< XAccessible >(mpAccessibleDocument); 1115 uno::Reference< XAccessible > xChild( (*vi)->pAccShape); 1116 aEvent.NewValue <<= xChild; 1117 mpAccessibleDocument->CommitChange(aEvent); 1118 } 1119 } 1120 SortedShapes::iterator vi = vecSelectedShapeRemove.begin(); 1121 for (; vi != vecSelectedShapeRemove.end() ; ++vi ) 1122 { 1123 AccessibleEventObject aEvent; 1124 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE; 1125 aEvent.Source = uno::Reference< XAccessible >(mpAccessibleDocument); 1126 uno::Reference< XAccessible > xChild( (*vi)->pAccShape); 1127 aEvent.NewValue <<= xChild; 1128 mpAccessibleDocument->CommitChange(aEvent); 1129 } 1130 std::for_each(aShapesList.begin(), aShapesList.end(), Destroy()); 1131 1132 return bResult; 1133 } 1134 1135 void ScChildrenShapes::FillSelectionSupplier() const 1136 { 1137 if (!xSelectionSupplier.is() && mpViewShell) 1138 { 1139 SfxViewFrame* pViewFrame = mpViewShell->GetViewFrame(); 1140 if (pViewFrame) 1141 { 1142 xSelectionSupplier = uno::Reference<view::XSelectionSupplier>(pViewFrame->GetFrame().GetController(), uno::UNO_QUERY); 1143 if (xSelectionSupplier.is()) 1144 { 1145 if (mpAccessibleDocument) 1146 xSelectionSupplier->addSelectionChangeListener(mpAccessibleDocument); 1147 uno::Reference<drawing::XShapes> xShapes (xSelectionSupplier->getSelection(), uno::UNO_QUERY); 1148 if (xShapes.is()) 1149 mnShapesSelected = xShapes->getCount(); 1150 } 1151 } 1152 } 1153 } 1154 1155 ScAddress* ScChildrenShapes::GetAnchor(const uno::Reference<drawing::XShape>& xShape) const 1156 { 1157 ScAddress* pAddress = NULL; 1158 if (mpViewShell) 1159 { 1160 SvxShape* pShapeImp = SvxShape::getImplementation(xShape); 1161 uno::Reference<beans::XPropertySet> xShapeProp(xShape, uno::UNO_QUERY); 1162 if (pShapeImp && xShapeProp.is()) 1163 { 1164 SdrObject *pSdrObj = pShapeImp->GetSdrObject(); 1165 if (pSdrObj) 1166 { 1167 if (ScDrawLayer::GetAnchor(pSdrObj) == SCA_CELL) 1168 { 1169 ScDocument* pDoc = mpViewShell->GetViewData()->GetDocument(); 1170 if (pDoc) 1171 { 1172 rtl::OUString sCaptionShape(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CaptionShape")); 1173 awt::Point aPoint(xShape->getPosition()); 1174 awt::Size aSize(xShape->getSize()); 1175 rtl::OUString sType(xShape->getShapeType()); 1176 Rectangle aRectangle(aPoint.X, aPoint.Y, aPoint.X + aSize.Width, aPoint.Y + aSize.Height); 1177 if ( sType.equals(sCaptionShape) ) 1178 { 1179 awt::Point aRelativeCaptionPoint; 1180 rtl::OUString sCaptionPoint( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" )); 1181 xShapeProp->getPropertyValue( sCaptionPoint ) >>= aRelativeCaptionPoint; 1182 Point aCoreRelativeCaptionPoint(aRelativeCaptionPoint.X, aRelativeCaptionPoint.Y); 1183 Point aCoreAbsoluteCaptionPoint(aPoint.X, aPoint.Y); 1184 aCoreAbsoluteCaptionPoint += aCoreRelativeCaptionPoint; 1185 aRectangle.Union(Rectangle(aCoreAbsoluteCaptionPoint, aCoreAbsoluteCaptionPoint)); 1186 } 1187 ScRange aRange = pDoc->GetRange(mpAccessibleDocument->getVisibleTable(), aRectangle); 1188 pAddress = new ScAddress(aRange.aStart); 1189 } 1190 } 1191 // else 1192 // do nothing, because it is always a NULL Pointer 1193 } 1194 } 1195 } 1196 1197 return pAddress; 1198 } 1199 1200 uno::Reference<XAccessibleRelationSet> ScChildrenShapes::GetRelationSet(const ScAccessibleShapeData* pData) const 1201 { 1202 utl::AccessibleRelationSetHelper* pRelationSet = new utl::AccessibleRelationSetHelper(); 1203 1204 if(pData && pRelationSet && mpAccessibleDocument) 1205 { 1206 uno::Reference<XAccessible> xAccessible = mpAccessibleDocument->GetAccessibleSpreadsheet(); // should be the current table 1207 if (pData->pRelationCell && xAccessible.is()) 1208 { 1209 uno::Reference<XAccessibleTable> xAccTable (xAccessible->getAccessibleContext(), uno::UNO_QUERY); 1210 if (xAccTable.is()) 1211 xAccessible = xAccTable->getAccessibleCellAt(pData->pRelationCell->Row(), pData->pRelationCell->Col()); 1212 } 1213 AccessibleRelation aRelation; 1214 aRelation.TargetSet.realloc(1); 1215 aRelation.TargetSet[0] = xAccessible; 1216 aRelation.RelationType = AccessibleRelationType::CONTROLLED_BY; 1217 pRelationSet->AddRelation(aRelation); 1218 } 1219 1220 return pRelationSet; 1221 } 1222 1223 void ScChildrenShapes::CheckWhetherAnchorChanged(const uno::Reference<drawing::XShape>& xShape) const 1224 { 1225 SortedShapes::iterator aItr; 1226 if (FindShape(xShape, aItr)) 1227 SetAnchor(xShape, *aItr); 1228 } 1229 1230 void ScChildrenShapes::SetAnchor(const uno::Reference<drawing::XShape>& xShape, ScAccessibleShapeData* pData) const 1231 { 1232 if (pData) 1233 { 1234 ScAddress* pAddress = GetAnchor(xShape); 1235 if ((pAddress && pData->pRelationCell && (*pAddress != *(pData->pRelationCell))) || 1236 (!pAddress && pData->pRelationCell) || (pAddress && !pData->pRelationCell)) 1237 { 1238 if (pData->pRelationCell) 1239 delete pData->pRelationCell; 1240 pData->pRelationCell = pAddress; 1241 if (pData->pAccShape) 1242 pData->pAccShape->SetRelationSet(GetRelationSet(pData)); 1243 } 1244 } 1245 } 1246 1247 void ScChildrenShapes::AddShape(const uno::Reference<drawing::XShape>& xShape, sal_Bool bCommitChange) const 1248 { 1249 SortedShapes::iterator aFindItr; 1250 if (!FindShape(xShape, aFindItr)) 1251 { 1252 ScAccessibleShapeData* pShape = new ScAccessibleShapeData(); 1253 pShape->xShape = xShape; 1254 SortedShapes::iterator aNewItr = maZOrderedShapes.insert(aFindItr, pShape); 1255 SetAnchor(xShape, pShape); 1256 1257 uno::Reference< beans::XPropertySet > xShapeProp(xShape, uno::UNO_QUERY); 1258 if (xShapeProp.is()) 1259 { 1260 uno::Any aPropAny = xShapeProp->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "LayerID" ))); 1261 sal_Int16 nLayerID = 0; 1262 if( aPropAny >>= nLayerID ) 1263 { 1264 if( (nLayerID == SC_LAYER_INTERN) || (nLayerID == SC_LAYER_HIDDEN) ) 1265 pShape->bSelectable = sal_False; 1266 else 1267 pShape->bSelectable = sal_True; 1268 } 1269 } 1270 1271 1272 if (!xSelectionSupplier.is()) 1273 throw uno::RuntimeException(); 1274 1275 uno::Reference<container::XEnumerationAccess> xEnumAcc(xSelectionSupplier->getSelection(), uno::UNO_QUERY); 1276 if (xEnumAcc.is()) 1277 { 1278 uno::Reference<container::XEnumeration> xEnum = xEnumAcc->createEnumeration(); 1279 if (xEnum.is()) 1280 { 1281 uno::Reference<drawing::XShape> xSelectedShape; 1282 sal_Bool bFound(sal_False); 1283 while (!bFound && xEnum->hasMoreElements()) 1284 { 1285 xEnum->nextElement() >>= xSelectedShape; 1286 if (xShape.is() && (xShape.get() == xSelectedShape.get())) 1287 { 1288 pShape->bSelected = sal_True; 1289 bFound = sal_True; 1290 } 1291 } 1292 } 1293 } 1294 if (mpAccessibleDocument && bCommitChange) 1295 { 1296 AccessibleEventObject aEvent; 1297 aEvent.EventId = AccessibleEventId::CHILD; 1298 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument); 1299 aEvent.NewValue <<= Get(aNewItr - maZOrderedShapes.begin()); 1300 1301 mpAccessibleDocument->CommitChange(aEvent); // new child - event 1302 } 1303 } 1304 else 1305 { 1306 DBG_ERRORFILE("shape is always in the list"); 1307 } 1308 } 1309 1310 void ScChildrenShapes::RemoveShape(const uno::Reference<drawing::XShape>& xShape) const 1311 { 1312 SortedShapes::iterator aItr; 1313 if (FindShape(xShape, aItr)) 1314 { 1315 if (mpAccessibleDocument) 1316 { 1317 uno::Reference<XAccessible> xOldAccessible (Get(aItr - maZOrderedShapes.begin())); 1318 1319 delete *aItr; 1320 maZOrderedShapes.erase(aItr); 1321 1322 AccessibleEventObject aEvent; 1323 aEvent.EventId = AccessibleEventId::CHILD; 1324 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument); 1325 aEvent.OldValue <<= uno::makeAny(xOldAccessible); 1326 1327 mpAccessibleDocument->CommitChange(aEvent); // child is gone - event 1328 } 1329 else 1330 { 1331 delete *aItr; 1332 maZOrderedShapes.erase(aItr); 1333 } 1334 } 1335 else 1336 { 1337 DBG_ERRORFILE("shape was not in internal list"); 1338 } 1339 } 1340 1341 sal_Bool ScChildrenShapes::FindShape(const uno::Reference<drawing::XShape>& xShape, ScChildrenShapes::SortedShapes::iterator& rItr) const 1342 { 1343 sal_Bool bResult(sal_False); 1344 ScAccessibleShapeData aShape; 1345 aShape.xShape = xShape; 1346 ScShapeDataLess aLess; 1347 rItr = std::lower_bound(maZOrderedShapes.begin(), maZOrderedShapes.end(), &aShape, aLess); 1348 if ((rItr != maZOrderedShapes.end()) && (*rItr != NULL) && ((*rItr)->xShape.get() == xShape.get())) 1349 bResult = sal_True; // if the shape is found 1350 1351 #ifdef DBG_UTIL // test whether it finds truly the correct shape (perhaps it is not really sorted) 1352 SortedShapes::iterator aDebugItr = maZOrderedShapes.begin(); 1353 SortedShapes::iterator aEndItr = maZOrderedShapes.end(); 1354 sal_Bool bFound(sal_False); 1355 while (!bFound && aDebugItr != aEndItr) 1356 { 1357 if (*aDebugItr && ((*aDebugItr)->xShape.get() == xShape.get())) 1358 bFound = sal_True; 1359 else 1360 ++aDebugItr; 1361 } 1362 sal_Bool bResult2 = (aDebugItr != maZOrderedShapes.end()); 1363 DBG_ASSERT((bResult == bResult2) && ((bResult && (rItr == aDebugItr)) || !bResult), "wrong Shape found"); 1364 #endif 1365 return bResult; 1366 } 1367 1368 sal_Int8 ScChildrenShapes::Compare(const ScAccessibleShapeData* pData1, 1369 const ScAccessibleShapeData* pData2) const 1370 { 1371 ScShapeDataLess aLess; 1372 1373 sal_Bool bResult1(aLess(pData1, pData2)); 1374 sal_Bool bResult2(aLess(pData2, pData1)); 1375 1376 sal_Int8 nResult(0); 1377 if (!bResult1 && bResult2) 1378 nResult = 1; 1379 else if (bResult1 && !bResult2) 1380 nResult = -1; 1381 1382 return nResult; 1383 } 1384 1385 struct ScVisAreaChanged 1386 { 1387 ScAccessibleDocument* mpAccDoc; 1388 ScVisAreaChanged(ScAccessibleDocument* pAccDoc) : mpAccDoc(pAccDoc) {} 1389 void operator() (const ScAccessibleShapeData* pAccShapeData) const 1390 { 1391 if (pAccShapeData && pAccShapeData->pAccShape) 1392 { 1393 pAccShapeData->pAccShape->ViewForwarderChanged(::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA, mpAccDoc); 1394 } 1395 } 1396 }; 1397 1398 void ScChildrenShapes::VisAreaChanged() const 1399 { 1400 ScVisAreaChanged aVisAreaChanged(mpAccessibleDocument); 1401 std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), aVisAreaChanged); 1402 } 1403 1404 // ============================================================================ 1405 1406 ScAccessibleDocument::ScAccessibleDocument( 1407 const uno::Reference<XAccessible>& rxParent, 1408 ScTabViewShell* pViewShell, 1409 ScSplitPos eSplitPos) 1410 : ScAccessibleDocumentBase(rxParent), 1411 mpViewShell(pViewShell), 1412 meSplitPos(eSplitPos), 1413 mpAccessibleSpreadsheet(NULL), 1414 mpChildrenShapes(NULL), 1415 mpTempAccEdit(NULL), 1416 mbCompleteSheetSelected(sal_False) 1417 { 1418 if (pViewShell) 1419 { 1420 pViewShell->AddAccessibilityObject(*this); 1421 Window *pWin = pViewShell->GetWindowByPos(eSplitPos); 1422 if( pWin ) 1423 { 1424 pWin->AddChildEventListener( LINK( this, ScAccessibleDocument, WindowChildEventListener )); 1425 sal_uInt16 nCount = pWin->GetChildCount(); 1426 for( sal_uInt16 i=0; i < nCount; ++i ) 1427 { 1428 Window *pChildWin = pWin->GetChild( i ); 1429 if( pChildWin && 1430 AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() ) 1431 AddChild( pChildWin->GetAccessible(), sal_False ); 1432 } 1433 } 1434 if (pViewShell->GetViewData()->HasEditView( eSplitPos )) 1435 { 1436 uno::Reference<XAccessible> xAcc = new ScAccessibleEditObject(this, pViewShell->GetViewData()->GetEditView(eSplitPos), 1437 pViewShell->GetWindowByPos(eSplitPos), GetCurrentCellName(), GetCurrentCellDescription(), 1438 CellInEditMode); 1439 AddChild(xAcc, sal_False); 1440 } 1441 } 1442 maVisArea = GetVisibleArea_Impl(); 1443 } 1444 1445 void ScAccessibleDocument::Init() 1446 { 1447 if(!mpChildrenShapes) 1448 mpChildrenShapes = new ScChildrenShapes(this, mpViewShell, meSplitPos); 1449 } 1450 1451 ScAccessibleDocument::~ScAccessibleDocument(void) 1452 { 1453 if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose) 1454 { 1455 // increment refcount to prevent double call off dtor 1456 osl_incrementInterlockedCount( &m_refCount ); 1457 dispose(); 1458 } 1459 } 1460 1461 void SAL_CALL ScAccessibleDocument::disposing() 1462 { 1463 ScUnoGuard aGuard; 1464 FreeAccessibleSpreadsheet(); 1465 if (mpViewShell) 1466 { 1467 Window *pWin = mpViewShell->GetWindowByPos(meSplitPos); 1468 if( pWin ) 1469 pWin->RemoveChildEventListener( LINK( this, ScAccessibleDocument, WindowChildEventListener )); 1470 1471 mpViewShell->RemoveAccessibilityObject(*this); 1472 mpViewShell = NULL; 1473 } 1474 if (mpChildrenShapes) 1475 DELETEZ(mpChildrenShapes); 1476 1477 ScAccessibleDocumentBase::disposing(); 1478 } 1479 1480 void SAL_CALL ScAccessibleDocument::disposing( const lang::EventObject& /* Source */ ) 1481 throw (uno::RuntimeException) 1482 { 1483 disposing(); 1484 } 1485 1486 //===== SfxListener ===================================================== 1487 1488 IMPL_LINK( ScAccessibleDocument, WindowChildEventListener, VclSimpleEvent*, pEvent ) 1489 { 1490 DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" ); 1491 if ( pEvent && pEvent->ISA( VclWindowEvent ) ) 1492 { 1493 VclWindowEvent *pVclEvent = static_cast< VclWindowEvent * >( pEvent ); 1494 DBG_ASSERT( pVclEvent->GetWindow(), "Window???" ); 1495 switch ( pVclEvent->GetId() ) 1496 { 1497 case VCLEVENT_WINDOW_SHOW: // send create on show for direct accessible children 1498 { 1499 Window* pChildWin = static_cast < Window * >( pVclEvent->GetData() ); 1500 if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() ) 1501 { 1502 AddChild( pChildWin->GetAccessible(), sal_True ); 1503 } 1504 } 1505 break; 1506 case VCLEVENT_WINDOW_HIDE: // send destroy on hide for direct accessible children 1507 { 1508 Window* pChildWin = static_cast < Window * >( pVclEvent->GetData() ); 1509 if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() ) 1510 { 1511 RemoveChild( pChildWin->GetAccessible(), sal_True ); 1512 } 1513 } 1514 break; 1515 } 1516 } 1517 return 0; 1518 } 1519 1520 void ScAccessibleDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) 1521 { 1522 if (rHint.ISA( ScAccGridWinFocusLostHint ) ) 1523 { 1524 const ScAccGridWinFocusLostHint& rRef = (const ScAccGridWinFocusLostHint&)rHint; 1525 if (rRef.GetOldGridWin() == meSplitPos) 1526 { 1527 if (mxTempAcc.is() && mpTempAccEdit) 1528 mpTempAccEdit->LostFocus(); 1529 else if (mpAccessibleSpreadsheet) 1530 mpAccessibleSpreadsheet->LostFocus(); 1531 else 1532 CommitFocusLost(); 1533 } 1534 } 1535 else if (rHint.ISA( ScAccGridWinFocusGotHint ) ) 1536 { 1537 const ScAccGridWinFocusGotHint& rRef = (const ScAccGridWinFocusGotHint&)rHint; 1538 if (rRef.GetNewGridWin() == meSplitPos) 1539 { 1540 uno::Reference<XAccessible> xAccessible; 1541 if (mpChildrenShapes) 1542 { 1543 sal_Bool bTabMarked(IsTableSelected()); 1544 xAccessible = mpChildrenShapes->GetSelected(0, bTabMarked); 1545 } 1546 if( xAccessible.is() ) 1547 { 1548 uno::Any aNewValue; 1549 aNewValue<<=AccessibleStateType::FOCUSED; 1550 static_cast< ::accessibility::AccessibleShape* >(xAccessible.get())-> 1551 CommitChange(AccessibleEventId::STATE_CHANGED, 1552 aNewValue, 1553 uno::Any() ); 1554 } 1555 else 1556 { 1557 if (mxTempAcc.is() && mpTempAccEdit) 1558 mpTempAccEdit->GotFocus(); 1559 else if (mpAccessibleSpreadsheet) 1560 mpAccessibleSpreadsheet->GotFocus(); 1561 else 1562 CommitFocusGained(); 1563 } 1564 } 1565 } 1566 else if (rHint.ISA( SfxSimpleHint )) 1567 { 1568 const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint; 1569 // only notify if child exist, otherwise it is not necessary 1570 if ((rRef.GetId() == SC_HINT_ACC_TABLECHANGED) && 1571 mpAccessibleSpreadsheet) 1572 { 1573 FreeAccessibleSpreadsheet(); 1574 if (mpChildrenShapes) 1575 DELETEZ(mpChildrenShapes); 1576 1577 // #124567# Accessibility: Shapes / form controls after reload not accessible 1578 if ( !mpChildrenShapes ) 1579 { 1580 mpChildrenShapes = new ScChildrenShapes( this, mpViewShell, meSplitPos ); 1581 } 1582 //Invoke Init() to rebuild the mpChildrenShapes variable 1583 this->Init(); 1584 AccessibleEventObject aEvent; 1585 aEvent.EventId = AccessibleEventId::INVALIDATE_ALL_CHILDREN; 1586 aEvent.Source = uno::Reference< XAccessibleContext >(this); 1587 CommitChange(aEvent); // all childs changed 1588 if (mpAccessibleSpreadsheet) 1589 mpAccessibleSpreadsheet->FireFirstCellFocus(); 1590 } 1591 else if (rRef.GetId() == SC_HINT_ACC_MAKEDRAWLAYER) 1592 { 1593 if (mpChildrenShapes) 1594 mpChildrenShapes->SetDrawBroadcaster(); 1595 } 1596 else if ((rRef.GetId() == SC_HINT_ACC_ENTEREDITMODE)) // this event comes only on creating edit field of a cell 1597 { 1598 if (mpViewShell && mpViewShell->GetViewData()->HasEditView(meSplitPos)) 1599 { 1600 EditEngine* pEditEng = mpViewShell->GetViewData()->GetEditView(meSplitPos)->GetEditEngine(); 1601 if (pEditEng && pEditEng->GetUpdateMode()) 1602 { 1603 mpTempAccEdit = new ScAccessibleEditObject(this, mpViewShell->GetViewData()->GetEditView(meSplitPos), 1604 mpViewShell->GetWindowByPos(meSplitPos), GetCurrentCellName(), 1605 rtl::OUString(String(ScResId(STR_ACC_EDITLINE_DESCR))), CellInEditMode); 1606 uno::Reference<XAccessible> xAcc = mpTempAccEdit; 1607 1608 AddChild(xAcc, sal_True); 1609 1610 if (mpAccessibleSpreadsheet) 1611 mpAccessibleSpreadsheet->LostFocus(); 1612 else 1613 CommitFocusLost(); 1614 1615 mpTempAccEdit->GotFocus(); 1616 } 1617 } 1618 } 1619 else if (rRef.GetId() == SC_HINT_ACC_LEAVEEDITMODE) 1620 { 1621 if (mxTempAcc.is()) 1622 { 1623 if (mpTempAccEdit) 1624 mpTempAccEdit->LostFocus(); 1625 1626 mpTempAccEdit = NULL; 1627 RemoveChild(mxTempAcc, sal_True); 1628 if (mpAccessibleSpreadsheet && mpViewShell->IsActive()) 1629 mpAccessibleSpreadsheet->GotFocus(); 1630 else if( mpViewShell->IsActive()) 1631 CommitFocusGained(); 1632 } 1633 } 1634 else if ((rRef.GetId() == SC_HINT_ACC_VISAREACHANGED) || (rRef.GetId() == SC_HINT_ACC_WINDOWRESIZED)) 1635 { 1636 Rectangle aOldVisArea(maVisArea); 1637 maVisArea = GetVisibleArea_Impl(); 1638 1639 if (maVisArea != aOldVisArea) 1640 { 1641 if (maVisArea.GetSize() != aOldVisArea.GetSize()) 1642 { 1643 AccessibleEventObject aEvent; 1644 aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED; 1645 aEvent.Source = uno::Reference< XAccessibleContext >(this); 1646 1647 CommitChange(aEvent); 1648 1649 if (mpAccessibleSpreadsheet) 1650 mpAccessibleSpreadsheet->BoundingBoxChanged(); 1651 } 1652 else if (mpAccessibleSpreadsheet) 1653 { 1654 mpAccessibleSpreadsheet->VisAreaChanged(); 1655 } 1656 if (mpChildrenShapes) 1657 mpChildrenShapes->VisAreaChanged(); 1658 } 1659 } 1660 } 1661 1662 ScAccessibleDocumentBase::Notify(rBC, rHint); 1663 } 1664 1665 void SAL_CALL ScAccessibleDocument::selectionChanged( const lang::EventObject& /* aEvent */ ) 1666 throw (uno::RuntimeException) 1667 { 1668 sal_Bool bSelectionChanged(sal_False); 1669 if (mpAccessibleSpreadsheet) 1670 { 1671 sal_Bool bOldSelected(mbCompleteSheetSelected); 1672 mbCompleteSheetSelected = IsTableSelected(); 1673 if (bOldSelected != mbCompleteSheetSelected) 1674 { 1675 mpAccessibleSpreadsheet->CompleteSelectionChanged(mbCompleteSheetSelected); 1676 bSelectionChanged = sal_True; 1677 } 1678 } 1679 1680 if (mpChildrenShapes && mpChildrenShapes->SelectionChanged()) 1681 bSelectionChanged = sal_True; 1682 1683 if (bSelectionChanged) 1684 { 1685 AccessibleEventObject aEvent; 1686 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; 1687 aEvent.Source = uno::Reference< XAccessibleContext >(this); 1688 1689 CommitChange(aEvent); 1690 } 1691 if(mpChildrenShapes ) 1692 { 1693 mpChildrenShapes->SelectionChanged(); 1694 } 1695 } 1696 1697 //===== XInterface ===================================================== 1698 1699 uno::Any SAL_CALL ScAccessibleDocument::queryInterface( uno::Type const & rType ) 1700 throw (uno::RuntimeException) 1701 { 1702 uno::Any aAnyTmp; 1703 if(rType == ::getCppuType((com::sun::star::uno::Reference<XAccessibleGetAccFlowTo> *)NULL) ) 1704 { 1705 com::sun::star::uno::Reference<XAccessibleGetAccFlowTo> AccFromXShape = this; 1706 aAnyTmp <<= AccFromXShape; 1707 return aAnyTmp; 1708 } 1709 uno::Any aAny (ScAccessibleDocumentImpl::queryInterface(rType)); 1710 return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType); 1711 } 1712 1713 void SAL_CALL ScAccessibleDocument::acquire() 1714 throw () 1715 { 1716 ScAccessibleContextBase::acquire(); 1717 } 1718 1719 void SAL_CALL ScAccessibleDocument::release() 1720 throw () 1721 { 1722 ScAccessibleContextBase::release(); 1723 } 1724 1725 //===== XAccessibleComponent ============================================ 1726 1727 uno::Reference< XAccessible > SAL_CALL ScAccessibleDocument::getAccessibleAtPoint( 1728 const awt::Point& rPoint ) 1729 throw (uno::RuntimeException) 1730 { 1731 uno::Reference<XAccessible> xAccessible = NULL; 1732 if (containsPoint(rPoint)) 1733 { 1734 ScUnoGuard aGuard; 1735 IsObjectValid(); 1736 if (mpChildrenShapes) 1737 xAccessible = mpChildrenShapes->GetAt(rPoint); 1738 if(!xAccessible.is()) 1739 { 1740 if (mxTempAcc.is()) 1741 { 1742 uno::Reference< XAccessibleContext > xCont(mxTempAcc->getAccessibleContext()); 1743 uno::Reference< XAccessibleComponent > xComp(xCont, uno::UNO_QUERY); 1744 if (xComp.is()) 1745 { 1746 Rectangle aBound(VCLRectangle(xComp->getBounds())); 1747 if (aBound.IsInside(VCLPoint(rPoint))) 1748 xAccessible = mxTempAcc; 1749 } 1750 } 1751 if (!xAccessible.is()) 1752 xAccessible = GetAccessibleSpreadsheet(); 1753 } 1754 } 1755 return xAccessible; 1756 } 1757 1758 void SAL_CALL ScAccessibleDocument::grabFocus( ) 1759 throw (uno::RuntimeException) 1760 { 1761 ScUnoGuard aGuard; 1762 IsObjectValid(); 1763 if (getAccessibleParent().is()) 1764 { 1765 uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY); 1766 if (xAccessibleComponent.is()) 1767 { 1768 xAccessibleComponent->grabFocus(); 1769 // grab only focus if it does not have the focus and it is not hidden 1770 if (mpViewShell && mpViewShell->GetViewData() && 1771 (mpViewShell->GetViewData()->GetActivePart() != meSplitPos) && 1772 mpViewShell->GetWindowByPos(meSplitPos)->IsVisible()) 1773 { 1774 mpViewShell->ActivatePart(meSplitPos); 1775 } 1776 } 1777 } 1778 } 1779 1780 //===== XAccessibleContext ============================================== 1781 1782 /// Return the number of currently visible children. 1783 sal_Int32 SAL_CALL 1784 ScAccessibleDocument::getAccessibleChildCount(void) 1785 throw (uno::RuntimeException) 1786 { 1787 ScUnoGuard aGuard; 1788 IsObjectValid(); 1789 sal_Int32 nCount(1); 1790 if (mpChildrenShapes) 1791 nCount = mpChildrenShapes->GetCount(); // returns the count of the shapes inclusive the table 1792 1793 if (mxTempAcc.is()) 1794 ++nCount; 1795 1796 return nCount; 1797 } 1798 1799 /// Return the specified child or NULL if index is invalid. 1800 uno::Reference<XAccessible> SAL_CALL 1801 ScAccessibleDocument::getAccessibleChild(sal_Int32 nIndex) 1802 throw (uno::RuntimeException, 1803 lang::IndexOutOfBoundsException) 1804 { 1805 ScUnoGuard aGuard; 1806 IsObjectValid(); 1807 uno::Reference<XAccessible> xAccessible; 1808 if (nIndex >= 0) 1809 { 1810 sal_Int32 nCount(1); 1811 if (mpChildrenShapes) 1812 { 1813 xAccessible = mpChildrenShapes->Get(nIndex); // returns NULL if it is the table or out of range 1814 nCount = mpChildrenShapes->GetCount(); //there is always a table 1815 } 1816 if (!xAccessible.is()) 1817 { 1818 if (nIndex < nCount) 1819 xAccessible = GetAccessibleSpreadsheet(); 1820 else if (nIndex == nCount && mxTempAcc.is()) 1821 xAccessible = mxTempAcc; 1822 } 1823 } 1824 1825 if (!xAccessible.is()) 1826 throw lang::IndexOutOfBoundsException(); 1827 1828 return xAccessible; 1829 } 1830 1831 /// Return the set of current states. 1832 uno::Reference<XAccessibleStateSet> SAL_CALL 1833 ScAccessibleDocument::getAccessibleStateSet(void) 1834 throw (uno::RuntimeException) 1835 { 1836 ScUnoGuard aGuard; 1837 uno::Reference<XAccessibleStateSet> xParentStates; 1838 if (getAccessibleParent().is()) 1839 { 1840 uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext(); 1841 xParentStates = xParentContext->getAccessibleStateSet(); 1842 } 1843 utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper(); 1844 if (IsDefunc(xParentStates)) 1845 pStateSet->AddState(AccessibleStateType::DEFUNC); 1846 else 1847 { 1848 if (IsEditable(xParentStates)) 1849 pStateSet->AddState(AccessibleStateType::EDITABLE); 1850 pStateSet->AddState(AccessibleStateType::ENABLED); 1851 pStateSet->AddState(AccessibleStateType::OPAQUE); 1852 if (isShowing()) 1853 pStateSet->AddState(AccessibleStateType::SHOWING); 1854 if (isVisible()) 1855 pStateSet->AddState(AccessibleStateType::VISIBLE); 1856 } 1857 return pStateSet; 1858 } 1859 1860 ::rtl::OUString SAL_CALL 1861 ScAccessibleDocument::getAccessibleName(void) 1862 throw (::com::sun::star::uno::RuntimeException) 1863 { 1864 rtl::OUString sName = String(ScResId(STR_ACC_DOC_SPREADSHEET)); 1865 ScDocument* pScDoc = GetDocument(); 1866 if ( pScDoc ) 1867 { 1868 rtl::OUString sFileName = pScDoc->getDocAccTitle(); 1869 if ( !sFileName.getLength() ) 1870 { 1871 SfxObjectShell* pObjSh = pScDoc->GetDocumentShell(); 1872 if ( pObjSh ) 1873 { 1874 sFileName = pObjSh->GetTitle( SFX_TITLE_APINAME ); 1875 } 1876 } 1877 rtl::OUString sReadOnly; 1878 if (pScDoc->getDocReadOnly()) 1879 { 1880 sReadOnly = String(ScResId(STR_ACC_DOC_SPREADSHEET_READONLY)); 1881 } 1882 if ( sFileName.getLength() ) 1883 { 1884 sName = sFileName + sReadOnly + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" - ")) + sName; 1885 } 1886 } 1887 return sName; 1888 } 1889 ///===== XAccessibleSelection =========================================== 1890 1891 void SAL_CALL 1892 ScAccessibleDocument::selectAccessibleChild( sal_Int32 nChildIndex ) 1893 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1894 { 1895 ScUnoGuard aGuard; 1896 IsObjectValid(); 1897 1898 if (mpChildrenShapes) 1899 { 1900 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table 1901 if (mxTempAcc.is()) 1902 ++nCount; 1903 if (nChildIndex < 0 || nChildIndex >= nCount) 1904 throw lang::IndexOutOfBoundsException(); 1905 1906 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex); 1907 if (xAccessible.is()) 1908 { 1909 sal_Bool bWasTableSelected(IsTableSelected()); 1910 1911 if (mpChildrenShapes) 1912 mpChildrenShapes->Select(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high 1913 1914 if (bWasTableSelected) 1915 mpViewShell->SelectAll(); 1916 } 1917 else 1918 { 1919 if (mpViewShell) 1920 mpViewShell->SelectAll(); 1921 } 1922 } 1923 } 1924 1925 sal_Bool SAL_CALL 1926 ScAccessibleDocument::isAccessibleChildSelected( sal_Int32 nChildIndex ) 1927 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1928 { 1929 ScUnoGuard aGuard; 1930 IsObjectValid(); 1931 sal_Bool bResult(sal_False); 1932 1933 if (mpChildrenShapes) 1934 { 1935 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table 1936 if (mxTempAcc.is()) 1937 ++nCount; 1938 if (nChildIndex < 0 || nChildIndex >= nCount) 1939 throw lang::IndexOutOfBoundsException(); 1940 1941 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex); 1942 if (xAccessible.is()) 1943 { 1944 uno::Reference<drawing::XShape> xShape; 1945 bResult = mpChildrenShapes->IsSelected(nChildIndex, xShape); // throws no lang::IndexOutOfBoundsException if Index is to high 1946 } 1947 else 1948 { 1949 if (mxTempAcc.is() && nChildIndex == nCount) 1950 bResult = sal_True; 1951 else 1952 bResult = IsTableSelected(); 1953 } 1954 } 1955 return bResult; 1956 } 1957 1958 void SAL_CALL 1959 ScAccessibleDocument::clearAccessibleSelection( ) 1960 throw (uno::RuntimeException) 1961 { 1962 ScUnoGuard aGuard; 1963 IsObjectValid(); 1964 1965 if (mpChildrenShapes) 1966 mpChildrenShapes->DeselectAll(); //deselects all (also the table) 1967 } 1968 1969 void SAL_CALL 1970 ScAccessibleDocument::selectAllAccessibleChildren( ) 1971 throw (uno::RuntimeException) 1972 { 1973 ScUnoGuard aGuard; 1974 IsObjectValid(); 1975 1976 if (mpChildrenShapes) 1977 mpChildrenShapes->SelectAll(); 1978 1979 // select table after shapes, because while selecting shapes the table will be deselected 1980 if (mpViewShell) 1981 { 1982 mpViewShell->SelectAll(); 1983 } 1984 } 1985 1986 sal_Int32 SAL_CALL 1987 ScAccessibleDocument::getSelectedAccessibleChildCount( ) 1988 throw (uno::RuntimeException) 1989 { 1990 ScUnoGuard aGuard; 1991 IsObjectValid(); 1992 sal_Int32 nCount(0); 1993 1994 if (mpChildrenShapes) 1995 nCount = mpChildrenShapes->GetSelectedCount(); 1996 1997 if (IsTableSelected()) 1998 ++nCount; 1999 2000 if (mxTempAcc.is()) 2001 ++nCount; 2002 2003 return nCount; 2004 } 2005 2006 uno::Reference<XAccessible > SAL_CALL 2007 ScAccessibleDocument::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) 2008 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2009 { 2010 ScUnoGuard aGuard; 2011 IsObjectValid(); 2012 uno::Reference<XAccessible> xAccessible; 2013 if (mpChildrenShapes) 2014 { 2015 sal_Int32 nCount(getSelectedAccessibleChildCount()); //all shapes and the table 2016 if (nSelectedChildIndex < 0 || nSelectedChildIndex >= nCount) 2017 throw lang::IndexOutOfBoundsException(); 2018 2019 sal_Bool bTabMarked(IsTableSelected()); 2020 2021 if (mpChildrenShapes) 2022 xAccessible = mpChildrenShapes->GetSelected(nSelectedChildIndex, bTabMarked); // throws no lang::IndexOutOfBoundsException if Index is to high 2023 if (mxTempAcc.is() && nSelectedChildIndex == nCount - 1) 2024 xAccessible = mxTempAcc; 2025 else if (bTabMarked) 2026 xAccessible = GetAccessibleSpreadsheet(); 2027 } 2028 2029 DBG_ASSERT(xAccessible.is(), "here should always be an accessible object or a exception throwed"); 2030 2031 return xAccessible; 2032 } 2033 2034 void SAL_CALL 2035 ScAccessibleDocument::deselectAccessibleChild( sal_Int32 nChildIndex ) 2036 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2037 { 2038 ScUnoGuard aGuard; 2039 IsObjectValid(); 2040 2041 if (mpChildrenShapes) 2042 { 2043 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table 2044 if (mxTempAcc.is()) 2045 ++nCount; 2046 if (nChildIndex < 0 || nChildIndex >= nCount) 2047 throw lang::IndexOutOfBoundsException(); 2048 2049 sal_Bool bTabMarked(IsTableSelected()); 2050 2051 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex); 2052 if (xAccessible.is()) 2053 { 2054 if (mpChildrenShapes) 2055 mpChildrenShapes->Deselect(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high 2056 2057 if (bTabMarked) 2058 mpViewShell->SelectAll(); // select the table again 2059 } 2060 else if (bTabMarked) 2061 mpViewShell->Unmark(); 2062 } 2063 } 2064 2065 //===== XServiceInfo ==================================================== 2066 2067 ::rtl::OUString SAL_CALL 2068 ScAccessibleDocument::getImplementationName(void) 2069 throw (uno::RuntimeException) 2070 { 2071 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDocument")); 2072 } 2073 2074 uno::Sequence< ::rtl::OUString> SAL_CALL 2075 ScAccessibleDocument::getSupportedServiceNames(void) 2076 throw (uno::RuntimeException) 2077 { 2078 uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames(); 2079 sal_Int32 nOldSize(aSequence.getLength()); 2080 aSequence.realloc(nOldSize + 1); 2081 ::rtl::OUString* pNames = aSequence.getArray(); 2082 2083 pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheetDocumentView")); 2084 2085 return aSequence; 2086 } 2087 2088 //===== XTypeProvider ======================================================= 2089 2090 uno::Sequence< uno::Type > SAL_CALL ScAccessibleDocument::getTypes() 2091 throw (uno::RuntimeException) 2092 { 2093 return comphelper::concatSequences(ScAccessibleDocumentImpl::getTypes(), ScAccessibleContextBase::getTypes()); 2094 } 2095 2096 uno::Sequence<sal_Int8> SAL_CALL 2097 ScAccessibleDocument::getImplementationId(void) 2098 throw (uno::RuntimeException) 2099 { 2100 ScUnoGuard aGuard; 2101 IsObjectValid(); 2102 static uno::Sequence<sal_Int8> aId; 2103 if (aId.getLength() == 0) 2104 { 2105 aId.realloc (16); 2106 rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True); 2107 } 2108 return aId; 2109 } 2110 2111 ///===== IAccessibleViewForwarder ======================================== 2112 2113 sal_Bool ScAccessibleDocument::IsValid (void) const 2114 { 2115 ScUnoGuard aGuard; 2116 IsObjectValid(); 2117 return (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose); 2118 } 2119 2120 Rectangle ScAccessibleDocument::GetVisibleArea_Impl() const 2121 { 2122 Rectangle aVisRect(GetBoundingBox()); 2123 2124 Point aPoint(mpViewShell->GetViewData()->GetPixPos(meSplitPos)); // returns a negative Point 2125 aPoint.setX(-aPoint.getX()); 2126 aPoint.setY(-aPoint.getY()); 2127 aVisRect.SetPos(aPoint); 2128 2129 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 2130 if (pWin) 2131 aVisRect = pWin->PixelToLogic(aVisRect, pWin->GetDrawMapMode()); 2132 2133 return aVisRect; 2134 } 2135 2136 Rectangle ScAccessibleDocument::GetVisibleArea() const 2137 { 2138 ScUnoGuard aGuard; 2139 IsObjectValid(); 2140 return maVisArea; 2141 } 2142 2143 Point ScAccessibleDocument::LogicToPixel (const Point& rPoint) const 2144 { 2145 ScUnoGuard aGuard; 2146 IsObjectValid(); 2147 Point aPoint; 2148 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 2149 if (pWin) 2150 { 2151 aPoint = pWin->LogicToPixel(rPoint, pWin->GetDrawMapMode()); 2152 aPoint += pWin->GetWindowExtentsRelative(NULL).TopLeft(); 2153 } 2154 return aPoint; 2155 } 2156 2157 Size ScAccessibleDocument::LogicToPixel (const Size& rSize) const 2158 { 2159 ScUnoGuard aGuard; 2160 IsObjectValid(); 2161 Size aSize; 2162 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 2163 if (pWin) 2164 aSize = pWin->LogicToPixel(rSize, pWin->GetDrawMapMode()); 2165 return aSize; 2166 } 2167 2168 Point ScAccessibleDocument::PixelToLogic (const Point& rPoint) const 2169 { 2170 ScUnoGuard aGuard; 2171 IsObjectValid(); 2172 Point aPoint; 2173 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 2174 if (pWin) 2175 { 2176 aPoint -= pWin->GetWindowExtentsRelative(NULL).TopLeft(); 2177 aPoint = pWin->PixelToLogic(rPoint, pWin->GetDrawMapMode()); 2178 } 2179 return aPoint; 2180 } 2181 2182 Size ScAccessibleDocument::PixelToLogic (const Size& rSize) const 2183 { 2184 ScUnoGuard aGuard; 2185 IsObjectValid(); 2186 Size aSize; 2187 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 2188 if (pWin) 2189 aSize = pWin->PixelToLogic(rSize, pWin->GetDrawMapMode()); 2190 return aSize; 2191 } 2192 2193 //===== internal ======================================================== 2194 2195 utl::AccessibleRelationSetHelper* ScAccessibleDocument::GetRelationSet(const ScAddress* pAddress) const 2196 { 2197 utl::AccessibleRelationSetHelper* pRelationSet = NULL; 2198 if (mpChildrenShapes) 2199 pRelationSet = mpChildrenShapes->GetRelationSet(pAddress); 2200 return pRelationSet; 2201 } 2202 2203 ::rtl::OUString SAL_CALL 2204 ScAccessibleDocument::createAccessibleDescription(void) 2205 throw (uno::RuntimeException) 2206 { 2207 rtl::OUString sDescription = String(ScResId(STR_ACC_DOC_DESCR)); 2208 return sDescription; 2209 } 2210 2211 ::rtl::OUString SAL_CALL 2212 ScAccessibleDocument::createAccessibleName(void) 2213 throw (uno::RuntimeException) 2214 { 2215 ScUnoGuard aGuard; 2216 IsObjectValid(); 2217 rtl::OUString sName = String(ScResId(STR_ACC_DOC_NAME)); 2218 sal_Int32 nNumber(sal_Int32(meSplitPos) + 1); 2219 sName += rtl::OUString::valueOf(nNumber); 2220 return sName; 2221 } 2222 2223 Rectangle ScAccessibleDocument::GetBoundingBoxOnScreen() const 2224 throw (uno::RuntimeException) 2225 { 2226 Rectangle aRect; 2227 if (mpViewShell) 2228 { 2229 Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos); 2230 if (pWindow) 2231 aRect = pWindow->GetWindowExtentsRelative(NULL); 2232 } 2233 return aRect; 2234 } 2235 2236 Rectangle ScAccessibleDocument::GetBoundingBox() const 2237 throw (uno::RuntimeException) 2238 { 2239 Rectangle aRect; 2240 if (mpViewShell) 2241 { 2242 Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos); 2243 if (pWindow) 2244 aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow()); 2245 } 2246 return aRect; 2247 } 2248 2249 SCTAB ScAccessibleDocument::getVisibleTable() const 2250 { 2251 SCTAB nVisibleTable(0); 2252 if (mpViewShell && mpViewShell->GetViewData()) 2253 nVisibleTable = mpViewShell->GetViewData()->GetTabNo(); 2254 return nVisibleTable; 2255 } 2256 2257 uno::Reference < XAccessible > 2258 ScAccessibleDocument::GetAccessibleSpreadsheet() 2259 { 2260 if (!mpAccessibleSpreadsheet && mpViewShell) 2261 { 2262 mpAccessibleSpreadsheet = new ScAccessibleSpreadsheet(this, mpViewShell, getVisibleTable(), meSplitPos); 2263 mpAccessibleSpreadsheet->acquire(); 2264 mpAccessibleSpreadsheet->Init(); 2265 mbCompleteSheetSelected = IsTableSelected(); 2266 } 2267 return mpAccessibleSpreadsheet; 2268 } 2269 2270 void ScAccessibleDocument::FreeAccessibleSpreadsheet() 2271 { 2272 if (mpAccessibleSpreadsheet) 2273 { 2274 mpAccessibleSpreadsheet->dispose(); 2275 mpAccessibleSpreadsheet->release(); 2276 mpAccessibleSpreadsheet = NULL; 2277 } 2278 } 2279 2280 sal_Bool ScAccessibleDocument::IsTableSelected() const 2281 { 2282 sal_Bool bResult (sal_False); 2283 if(mpViewShell) 2284 { 2285 SCTAB nTab(getVisibleTable()); 2286 //#103800#; use a copy of MarkData 2287 ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData()); 2288 aMarkData.MarkToMulti(); 2289 if (aMarkData.IsAllMarked(ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab)))) 2290 bResult = sal_True; 2291 } 2292 return bResult; 2293 } 2294 2295 sal_Bool ScAccessibleDocument::IsDefunc( 2296 const uno::Reference<XAccessibleStateSet>& rxParentStates) 2297 { 2298 return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() || 2299 (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC)); 2300 } 2301 2302 sal_Bool ScAccessibleDocument::IsEditable( 2303 const uno::Reference<XAccessibleStateSet>& /* rxParentStates */) 2304 { 2305 // what is with document protection or readonly documents? 2306 return sal_True; 2307 } 2308 2309 void ScAccessibleDocument::AddChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent) 2310 { 2311 DBG_ASSERT(!mxTempAcc.is(), "this object should be removed before"); 2312 if (xAcc.is()) 2313 { 2314 mxTempAcc = xAcc; 2315 if( bFireEvent ) 2316 { 2317 AccessibleEventObject aEvent; 2318 aEvent.Source = uno::Reference<XAccessibleContext>(this); 2319 aEvent.EventId = AccessibleEventId::CHILD; 2320 aEvent.NewValue <<= mxTempAcc; 2321 CommitChange( aEvent ); 2322 } 2323 } 2324 } 2325 2326 void ScAccessibleDocument::RemoveChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent) 2327 { 2328 DBG_ASSERT(mxTempAcc.is(), "this object should be added before"); 2329 if (xAcc.is()) 2330 { 2331 DBG_ASSERT(xAcc.get() == mxTempAcc.get(), "only the same object should be removed"); 2332 if( bFireEvent ) 2333 { 2334 AccessibleEventObject aEvent; 2335 aEvent.Source = uno::Reference<XAccessibleContext>(this); 2336 aEvent.EventId = AccessibleEventId::CHILD; 2337 aEvent.OldValue <<= mxTempAcc; 2338 CommitChange( aEvent ); 2339 } 2340 mxTempAcc = NULL; 2341 } 2342 } 2343 2344 rtl::OUString ScAccessibleDocument::GetCurrentCellName() const 2345 { 2346 String sName( ScResId(STR_ACC_CELL_NAME) ); 2347 if (mpViewShell) 2348 { 2349 String sAddress; 2350 // Document not needed, because only the cell address, but not the tablename is needed 2351 mpViewShell->GetViewData()->GetCurPos().Format( sAddress, SCA_VALID, NULL ); 2352 sName.SearchAndReplaceAscii("%1", sAddress); 2353 } 2354 return rtl::OUString(sName); 2355 } 2356 2357 rtl::OUString ScAccessibleDocument::GetCurrentCellDescription() const 2358 { 2359 return rtl::OUString(); 2360 } 2361 ScDocument *ScAccessibleDocument::GetDocument() const 2362 { 2363 return mpViewShell ? mpViewShell->GetViewData()->GetDocument() : NULL; 2364 } 2365 ScAddress ScAccessibleDocument::GetCurCellAddress() const 2366 { 2367 return mpViewShell ? mpViewShell->GetViewData()->GetCurPos() :ScAddress(); 2368 } 2369 uno::Any SAL_CALL ScAccessibleDocument::getExtendedAttributes() 2370 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 2371 { 2372 2373 uno::Any anyAtrribute; 2374 2375 rtl::OUString sName; 2376 rtl::OUString sValue; 2377 sal_uInt16 sheetIndex; 2378 String sSheetName; 2379 sheetIndex = getVisibleTable(); 2380 if(GetDocument()==NULL) 2381 return anyAtrribute; 2382 GetDocument()->GetName(sheetIndex,sSheetName); 2383 sName = rtl::OUString::createFromAscii("page-name:"); 2384 sValue = sName + sSheetName ; 2385 sName = rtl::OUString::createFromAscii(";page-number:"); 2386 sValue += sName; 2387 sValue += String::CreateFromInt32(sheetIndex+1) ; 2388 sName = rtl::OUString::createFromAscii(";total-pages:"); 2389 sValue += sName; 2390 sValue += String::CreateFromInt32(GetDocument()->GetTableCount()); 2391 sValue += rtl::OUString::createFromAscii(";"); 2392 anyAtrribute <<= sValue; 2393 return anyAtrribute; 2394 } 2395 com::sun::star::uno::Sequence< com::sun::star::uno::Any > ScAccessibleDocument::GetScAccFlowToSequence() 2396 { 2397 if ( getAccessibleChildCount() ) 2398 { 2399 uno::Reference < XAccessible > xSCTableAcc = getAccessibleChild( 0 ); // table 2400 if ( xSCTableAcc.is() ) 2401 { 2402 uno::Reference < XAccessibleSelection > xAccSelection( xSCTableAcc, uno::UNO_QUERY ); 2403 sal_Int32 nSelCount = xAccSelection->getSelectedAccessibleChildCount(); 2404 if( nSelCount ) 2405 { 2406 uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 ); // selected cell 2407 if ( xSel.is() ) 2408 { 2409 uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() ); 2410 if ( xSelContext.is() ) 2411 { 2412 if ( xSelContext->getAccessibleRole() == AccessibleRole::TABLE_CELL ) 2413 { 2414 sal_Int32 nParaCount = 0; 2415 uno::Sequence <uno::Any> aSequence(nSelCount); 2416 for ( sal_Int32 i = 0; i < nSelCount; i++ ) 2417 { 2418 xSel = xAccSelection->getSelectedAccessibleChild( i ) ; 2419 if ( xSel.is() ) 2420 { 2421 xSelContext = xSel->getAccessibleContext(); 2422 if ( xSelContext.is() ) 2423 { 2424 if ( xSelContext->getAccessibleRole() == AccessibleRole::TABLE_CELL ) 2425 { 2426 aSequence[nParaCount] = uno::makeAny( xSel ); 2427 nParaCount++; 2428 } 2429 } 2430 } 2431 } 2432 return aSequence; 2433 } 2434 } 2435 } 2436 } 2437 } 2438 } 2439 uno::Sequence <uno::Any> aEmpty; 2440 return aEmpty; 2441 } 2442 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > 2443 SAL_CALL ScAccessibleDocument::get_AccFlowTo(const ::com::sun::star::uno::Any& rAny, sal_Int32 nType) 2444 throw ( ::com::sun::star::uno::RuntimeException ) 2445 { 2446 const sal_Int32 SPELLCHECKFLOWTO = 1; 2447 const sal_Int32 FINDREPLACEFLOWTO = 2; 2448 if ( nType == SPELLCHECKFLOWTO ) 2449 { 2450 uno::Reference< ::com::sun::star::drawing::XShape > xShape; 2451 rAny >>= xShape; 2452 if ( xShape.is() ) 2453 { 2454 uno::Reference < XAccessible > xAcc = mpChildrenShapes->GetAccessibleCaption(xShape); 2455 uno::Reference < XAccessibleSelection > xAccSelection( xAcc, uno::UNO_QUERY ); 2456 if ( xAccSelection.is() ) 2457 { 2458 if ( xAccSelection->getSelectedAccessibleChildCount() ) 2459 { 2460 uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 ); 2461 if ( xSel.is() ) 2462 { 2463 uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() ); 2464 if ( xSelContext.is() ) 2465 { 2466 //if in sw we find the selected paragraph here 2467 if ( xSelContext->getAccessibleRole() == AccessibleRole::PARAGRAPH ) 2468 { 2469 uno::Sequence<uno::Any> aRet( 1 ); 2470 aRet[0] = uno::makeAny( xSel ); 2471 return aRet; 2472 } 2473 } 2474 } 2475 } 2476 } 2477 } 2478 else 2479 { 2480 if ( getSelectedAccessibleChildCount() ) 2481 { 2482 uno::Reference < XAccessible > xSel = getSelectedAccessibleChild( 0 ); 2483 if ( xSel.is() ) 2484 { 2485 uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() ); 2486 if ( xSelContext.is() ) 2487 { 2488 uno::Reference < XAccessibleSelection > xAccChildSelection( xSel, uno::UNO_QUERY ); 2489 if ( xAccChildSelection.is() ) 2490 { 2491 if ( xAccChildSelection->getSelectedAccessibleChildCount() ) 2492 { 2493 uno::Reference < XAccessible > xChildSel = xAccChildSelection->getSelectedAccessibleChild( 0 ); 2494 if ( xChildSel.is() ) 2495 { 2496 uno::Reference < ::com::sun::star::accessibility::XAccessibleContext > xChildSelContext( xChildSel->getAccessibleContext() ); 2497 if ( xChildSelContext.is() && 2498 xChildSelContext->getAccessibleRole() == ::com::sun::star::accessibility::AccessibleRole::PARAGRAPH ) 2499 { 2500 uno::Sequence<uno::Any> aRet( 1 ); 2501 aRet[0] = uno::makeAny( xChildSel ); 2502 return aRet; 2503 } 2504 } 2505 } 2506 } 2507 } 2508 } 2509 } 2510 } 2511 } 2512 else if ( nType == FINDREPLACEFLOWTO ) 2513 { 2514 sal_Bool bSuccess(sal_False); 2515 rAny >>= bSuccess; 2516 if ( bSuccess ) 2517 { 2518 uno::Sequence< uno::Any> aSeq = GetScAccFlowToSequence(); 2519 if ( aSeq.getLength() ) 2520 { 2521 return aSeq; 2522 } 2523 else if( mpAccessibleSpreadsheet ) 2524 { 2525 uno::Reference < XAccessible > xFindCellAcc = mpAccessibleSpreadsheet->GetActiveCell(); 2526 // add xFindCellAcc to the return the Sequence 2527 uno::Sequence< uno::Any> aSeq2(1); 2528 aSeq2[0] = uno::makeAny( xFindCellAcc ); 2529 return aSeq2; 2530 } 2531 } 2532 } 2533 uno::Sequence< uno::Any> aEmpty; 2534 return aEmpty; 2535 } 2536 void ScAccessibleDocument::SwitchViewFireFocus() 2537 { 2538 if (mpAccessibleSpreadsheet) 2539 { 2540 mpAccessibleSpreadsheet->FireFirstCellFocus(); 2541 } 2542 } 2543 2544 sal_Int32 SAL_CALL ScAccessibleDocument::getForeground( ) 2545 throw (uno::RuntimeException) 2546 { 2547 return COL_BLACK; 2548 } 2549 2550 sal_Int32 SAL_CALL ScAccessibleDocument::getBackground( ) 2551 throw (uno::RuntimeException) 2552 { 2553 ScUnoGuard aGuard; 2554 IsObjectValid(); 2555 return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor; 2556 } 2557 2558