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) 1629 if (mpAccessibleSpreadsheet && mpViewShell->IsActive()) 1630 mpAccessibleSpreadsheet->GotFocus(); 1631 //else 1632 else if( mpViewShell->IsActive()) 1633 CommitFocusGained(); 1634 } 1635 } 1636 else if ((rRef.GetId() == SC_HINT_ACC_VISAREACHANGED) || (rRef.GetId() == SC_HINT_ACC_WINDOWRESIZED)) 1637 { 1638 Rectangle aOldVisArea(maVisArea); 1639 maVisArea = GetVisibleArea_Impl(); 1640 1641 if (maVisArea != aOldVisArea) 1642 { 1643 if (maVisArea.GetSize() != aOldVisArea.GetSize()) 1644 { 1645 AccessibleEventObject aEvent; 1646 aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED; 1647 aEvent.Source = uno::Reference< XAccessibleContext >(this); 1648 1649 CommitChange(aEvent); 1650 1651 if (mpAccessibleSpreadsheet) 1652 mpAccessibleSpreadsheet->BoundingBoxChanged(); 1653 } 1654 else if (mpAccessibleSpreadsheet) 1655 { 1656 mpAccessibleSpreadsheet->VisAreaChanged(); 1657 } 1658 if (mpChildrenShapes) 1659 mpChildrenShapes->VisAreaChanged(); 1660 } 1661 } 1662 } 1663 1664 ScAccessibleDocumentBase::Notify(rBC, rHint); 1665 } 1666 1667 void SAL_CALL ScAccessibleDocument::selectionChanged( const lang::EventObject& /* aEvent */ ) 1668 throw (uno::RuntimeException) 1669 { 1670 sal_Bool bSelectionChanged(sal_False); 1671 if (mpAccessibleSpreadsheet) 1672 { 1673 sal_Bool bOldSelected(mbCompleteSheetSelected); 1674 mbCompleteSheetSelected = IsTableSelected(); 1675 if (bOldSelected != mbCompleteSheetSelected) 1676 { 1677 mpAccessibleSpreadsheet->CompleteSelectionChanged(mbCompleteSheetSelected); 1678 bSelectionChanged = sal_True; 1679 } 1680 } 1681 1682 if (mpChildrenShapes && mpChildrenShapes->SelectionChanged()) 1683 bSelectionChanged = sal_True; 1684 1685 if (bSelectionChanged) 1686 { 1687 AccessibleEventObject aEvent; 1688 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; 1689 aEvent.Source = uno::Reference< XAccessibleContext >(this); 1690 1691 CommitChange(aEvent); 1692 } 1693 if(mpChildrenShapes ) 1694 { 1695 mpChildrenShapes->SelectionChanged(); 1696 } 1697 } 1698 1699 //===== XInterface ===================================================== 1700 1701 uno::Any SAL_CALL ScAccessibleDocument::queryInterface( uno::Type const & rType ) 1702 throw (uno::RuntimeException) 1703 { 1704 uno::Any aAnyTmp; 1705 if(rType == ::getCppuType((com::sun::star::uno::Reference<XAccessibleGetAccFlowTo> *)NULL) ) 1706 { 1707 com::sun::star::uno::Reference<XAccessibleGetAccFlowTo> AccFromXShape = this; 1708 aAnyTmp <<= AccFromXShape; 1709 return aAnyTmp; 1710 } 1711 uno::Any aAny (ScAccessibleDocumentImpl::queryInterface(rType)); 1712 return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType); 1713 } 1714 1715 void SAL_CALL ScAccessibleDocument::acquire() 1716 throw () 1717 { 1718 ScAccessibleContextBase::acquire(); 1719 } 1720 1721 void SAL_CALL ScAccessibleDocument::release() 1722 throw () 1723 { 1724 ScAccessibleContextBase::release(); 1725 } 1726 1727 //===== XAccessibleComponent ============================================ 1728 1729 uno::Reference< XAccessible > SAL_CALL ScAccessibleDocument::getAccessibleAtPoint( 1730 const awt::Point& rPoint ) 1731 throw (uno::RuntimeException) 1732 { 1733 uno::Reference<XAccessible> xAccessible = NULL; 1734 if (containsPoint(rPoint)) 1735 { 1736 ScUnoGuard aGuard; 1737 IsObjectValid(); 1738 if (mpChildrenShapes) 1739 xAccessible = mpChildrenShapes->GetAt(rPoint); 1740 if(!xAccessible.is()) 1741 { 1742 if (mxTempAcc.is()) 1743 { 1744 uno::Reference< XAccessibleContext > xCont(mxTempAcc->getAccessibleContext()); 1745 uno::Reference< XAccessibleComponent > xComp(xCont, uno::UNO_QUERY); 1746 if (xComp.is()) 1747 { 1748 Rectangle aBound(VCLRectangle(xComp->getBounds())); 1749 if (aBound.IsInside(VCLPoint(rPoint))) 1750 xAccessible = mxTempAcc; 1751 } 1752 } 1753 if (!xAccessible.is()) 1754 xAccessible = GetAccessibleSpreadsheet(); 1755 } 1756 } 1757 return xAccessible; 1758 } 1759 1760 void SAL_CALL ScAccessibleDocument::grabFocus( ) 1761 throw (uno::RuntimeException) 1762 { 1763 ScUnoGuard aGuard; 1764 IsObjectValid(); 1765 if (getAccessibleParent().is()) 1766 { 1767 uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY); 1768 if (xAccessibleComponent.is()) 1769 { 1770 xAccessibleComponent->grabFocus(); 1771 // grab only focus if it does not have the focus and it is not hidden 1772 if (mpViewShell && mpViewShell->GetViewData() && 1773 (mpViewShell->GetViewData()->GetActivePart() != meSplitPos) && 1774 mpViewShell->GetWindowByPos(meSplitPos)->IsVisible()) 1775 { 1776 mpViewShell->ActivatePart(meSplitPos); 1777 } 1778 } 1779 } 1780 } 1781 1782 //===== XAccessibleContext ============================================== 1783 1784 /// Return the number of currently visible children. 1785 sal_Int32 SAL_CALL 1786 ScAccessibleDocument::getAccessibleChildCount(void) 1787 throw (uno::RuntimeException) 1788 { 1789 ScUnoGuard aGuard; 1790 IsObjectValid(); 1791 sal_Int32 nCount(1); 1792 if (mpChildrenShapes) 1793 nCount = mpChildrenShapes->GetCount(); // returns the count of the shapes inclusive the table 1794 1795 if (mxTempAcc.is()) 1796 ++nCount; 1797 1798 return nCount; 1799 } 1800 1801 /// Return the specified child or NULL if index is invalid. 1802 uno::Reference<XAccessible> SAL_CALL 1803 ScAccessibleDocument::getAccessibleChild(sal_Int32 nIndex) 1804 throw (uno::RuntimeException, 1805 lang::IndexOutOfBoundsException) 1806 { 1807 ScUnoGuard aGuard; 1808 IsObjectValid(); 1809 uno::Reference<XAccessible> xAccessible; 1810 if (nIndex >= 0) 1811 { 1812 sal_Int32 nCount(1); 1813 if (mpChildrenShapes) 1814 { 1815 xAccessible = mpChildrenShapes->Get(nIndex); // returns NULL if it is the table or out of range 1816 nCount = mpChildrenShapes->GetCount(); //there is always a table 1817 } 1818 if (!xAccessible.is()) 1819 { 1820 if (nIndex < nCount) 1821 xAccessible = GetAccessibleSpreadsheet(); 1822 else if (nIndex == nCount && mxTempAcc.is()) 1823 xAccessible = mxTempAcc; 1824 } 1825 } 1826 1827 if (!xAccessible.is()) 1828 throw lang::IndexOutOfBoundsException(); 1829 1830 return xAccessible; 1831 } 1832 1833 /// Return the set of current states. 1834 uno::Reference<XAccessibleStateSet> SAL_CALL 1835 ScAccessibleDocument::getAccessibleStateSet(void) 1836 throw (uno::RuntimeException) 1837 { 1838 ScUnoGuard aGuard; 1839 uno::Reference<XAccessibleStateSet> xParentStates; 1840 if (getAccessibleParent().is()) 1841 { 1842 uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext(); 1843 xParentStates = xParentContext->getAccessibleStateSet(); 1844 } 1845 utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper(); 1846 if (IsDefunc(xParentStates)) 1847 pStateSet->AddState(AccessibleStateType::DEFUNC); 1848 else 1849 { 1850 if (IsEditable(xParentStates)) 1851 pStateSet->AddState(AccessibleStateType::EDITABLE); 1852 pStateSet->AddState(AccessibleStateType::ENABLED); 1853 pStateSet->AddState(AccessibleStateType::OPAQUE); 1854 if (isShowing()) 1855 pStateSet->AddState(AccessibleStateType::SHOWING); 1856 if (isVisible()) 1857 pStateSet->AddState(AccessibleStateType::VISIBLE); 1858 } 1859 return pStateSet; 1860 } 1861 1862 ::rtl::OUString SAL_CALL 1863 ScAccessibleDocument::getAccessibleName(void) 1864 throw (::com::sun::star::uno::RuntimeException) 1865 { 1866 rtl::OUString sName = String(ScResId(STR_ACC_DOC_SPREADSHEET)); 1867 ScDocument* pScDoc = GetDocument(); 1868 if ( pScDoc ) 1869 { 1870 rtl::OUString sFileName = pScDoc->getDocAccTitle(); 1871 if ( !sFileName.getLength() ) 1872 { 1873 SfxObjectShell* pObjSh = pScDoc->GetDocumentShell(); 1874 if ( pObjSh ) 1875 { 1876 sFileName = pObjSh->GetTitle( SFX_TITLE_APINAME ); 1877 } 1878 } 1879 rtl::OUString sReadOnly; 1880 if (pScDoc->getDocReadOnly()) 1881 { 1882 sReadOnly = String(ScResId(STR_ACC_DOC_SPREADSHEET_READONLY)); 1883 } 1884 if ( sFileName.getLength() ) 1885 { 1886 sName = sFileName + sReadOnly + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" - ")) + sName; 1887 } 1888 } 1889 return sName; 1890 } 1891 ///===== XAccessibleSelection =========================================== 1892 1893 void SAL_CALL 1894 ScAccessibleDocument::selectAccessibleChild( sal_Int32 nChildIndex ) 1895 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1896 { 1897 ScUnoGuard aGuard; 1898 IsObjectValid(); 1899 1900 if (mpChildrenShapes) 1901 { 1902 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table 1903 if (mxTempAcc.is()) 1904 ++nCount; 1905 if (nChildIndex < 0 || nChildIndex >= nCount) 1906 throw lang::IndexOutOfBoundsException(); 1907 1908 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex); 1909 if (xAccessible.is()) 1910 { 1911 sal_Bool bWasTableSelected(IsTableSelected()); 1912 1913 if (mpChildrenShapes) 1914 mpChildrenShapes->Select(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high 1915 1916 if (bWasTableSelected) 1917 mpViewShell->SelectAll(); 1918 } 1919 else 1920 { 1921 if (mpViewShell) 1922 mpViewShell->SelectAll(); 1923 } 1924 } 1925 } 1926 1927 sal_Bool SAL_CALL 1928 ScAccessibleDocument::isAccessibleChildSelected( sal_Int32 nChildIndex ) 1929 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1930 { 1931 ScUnoGuard aGuard; 1932 IsObjectValid(); 1933 sal_Bool bResult(sal_False); 1934 1935 if (mpChildrenShapes) 1936 { 1937 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table 1938 if (mxTempAcc.is()) 1939 ++nCount; 1940 if (nChildIndex < 0 || nChildIndex >= nCount) 1941 throw lang::IndexOutOfBoundsException(); 1942 1943 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex); 1944 if (xAccessible.is()) 1945 { 1946 uno::Reference<drawing::XShape> xShape; 1947 bResult = mpChildrenShapes->IsSelected(nChildIndex, xShape); // throws no lang::IndexOutOfBoundsException if Index is to high 1948 } 1949 else 1950 { 1951 if (mxTempAcc.is() && nChildIndex == nCount) 1952 bResult = sal_True; 1953 else 1954 bResult = IsTableSelected(); 1955 } 1956 } 1957 return bResult; 1958 } 1959 1960 void SAL_CALL 1961 ScAccessibleDocument::clearAccessibleSelection( ) 1962 throw (uno::RuntimeException) 1963 { 1964 ScUnoGuard aGuard; 1965 IsObjectValid(); 1966 1967 if (mpChildrenShapes) 1968 mpChildrenShapes->DeselectAll(); //deselects all (also the table) 1969 } 1970 1971 void SAL_CALL 1972 ScAccessibleDocument::selectAllAccessibleChildren( ) 1973 throw (uno::RuntimeException) 1974 { 1975 ScUnoGuard aGuard; 1976 IsObjectValid(); 1977 1978 if (mpChildrenShapes) 1979 mpChildrenShapes->SelectAll(); 1980 1981 // select table after shapes, because while selecting shapes the table will be deselected 1982 if (mpViewShell) 1983 { 1984 mpViewShell->SelectAll(); 1985 } 1986 } 1987 1988 sal_Int32 SAL_CALL 1989 ScAccessibleDocument::getSelectedAccessibleChildCount( ) 1990 throw (uno::RuntimeException) 1991 { 1992 ScUnoGuard aGuard; 1993 IsObjectValid(); 1994 sal_Int32 nCount(0); 1995 1996 if (mpChildrenShapes) 1997 nCount = mpChildrenShapes->GetSelectedCount(); 1998 1999 if (IsTableSelected()) 2000 ++nCount; 2001 2002 if (mxTempAcc.is()) 2003 ++nCount; 2004 2005 return nCount; 2006 } 2007 2008 uno::Reference<XAccessible > SAL_CALL 2009 ScAccessibleDocument::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) 2010 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2011 { 2012 ScUnoGuard aGuard; 2013 IsObjectValid(); 2014 uno::Reference<XAccessible> xAccessible; 2015 if (mpChildrenShapes) 2016 { 2017 sal_Int32 nCount(getSelectedAccessibleChildCount()); //all shapes and the table 2018 if (nSelectedChildIndex < 0 || nSelectedChildIndex >= nCount) 2019 throw lang::IndexOutOfBoundsException(); 2020 2021 sal_Bool bTabMarked(IsTableSelected()); 2022 2023 if (mpChildrenShapes) 2024 xAccessible = mpChildrenShapes->GetSelected(nSelectedChildIndex, bTabMarked); // throws no lang::IndexOutOfBoundsException if Index is to high 2025 if (mxTempAcc.is() && nSelectedChildIndex == nCount - 1) 2026 xAccessible = mxTempAcc; 2027 else if (bTabMarked) 2028 xAccessible = GetAccessibleSpreadsheet(); 2029 } 2030 2031 DBG_ASSERT(xAccessible.is(), "here should always be an accessible object or a exception throwed"); 2032 2033 return xAccessible; 2034 } 2035 2036 void SAL_CALL 2037 ScAccessibleDocument::deselectAccessibleChild( sal_Int32 nChildIndex ) 2038 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2039 { 2040 ScUnoGuard aGuard; 2041 IsObjectValid(); 2042 2043 if (mpChildrenShapes) 2044 { 2045 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table 2046 if (mxTempAcc.is()) 2047 ++nCount; 2048 if (nChildIndex < 0 || nChildIndex >= nCount) 2049 throw lang::IndexOutOfBoundsException(); 2050 2051 sal_Bool bTabMarked(IsTableSelected()); 2052 2053 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex); 2054 if (xAccessible.is()) 2055 { 2056 if (mpChildrenShapes) 2057 mpChildrenShapes->Deselect(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high 2058 2059 if (bTabMarked) 2060 mpViewShell->SelectAll(); // select the table again 2061 } 2062 else if (bTabMarked) 2063 mpViewShell->Unmark(); 2064 } 2065 } 2066 2067 //===== XServiceInfo ==================================================== 2068 2069 ::rtl::OUString SAL_CALL 2070 ScAccessibleDocument::getImplementationName(void) 2071 throw (uno::RuntimeException) 2072 { 2073 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDocument")); 2074 } 2075 2076 uno::Sequence< ::rtl::OUString> SAL_CALL 2077 ScAccessibleDocument::getSupportedServiceNames(void) 2078 throw (uno::RuntimeException) 2079 { 2080 uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames(); 2081 sal_Int32 nOldSize(aSequence.getLength()); 2082 aSequence.realloc(nOldSize + 1); 2083 ::rtl::OUString* pNames = aSequence.getArray(); 2084 2085 pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheetDocumentView")); 2086 2087 return aSequence; 2088 } 2089 2090 //===== XTypeProvider ======================================================= 2091 2092 uno::Sequence< uno::Type > SAL_CALL ScAccessibleDocument::getTypes() 2093 throw (uno::RuntimeException) 2094 { 2095 return comphelper::concatSequences(ScAccessibleDocumentImpl::getTypes(), ScAccessibleContextBase::getTypes()); 2096 } 2097 2098 uno::Sequence<sal_Int8> SAL_CALL 2099 ScAccessibleDocument::getImplementationId(void) 2100 throw (uno::RuntimeException) 2101 { 2102 ScUnoGuard aGuard; 2103 IsObjectValid(); 2104 static uno::Sequence<sal_Int8> aId; 2105 if (aId.getLength() == 0) 2106 { 2107 aId.realloc (16); 2108 rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True); 2109 } 2110 return aId; 2111 } 2112 2113 ///===== IAccessibleViewForwarder ======================================== 2114 2115 sal_Bool ScAccessibleDocument::IsValid (void) const 2116 { 2117 ScUnoGuard aGuard; 2118 IsObjectValid(); 2119 return (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose); 2120 } 2121 2122 Rectangle ScAccessibleDocument::GetVisibleArea_Impl() const 2123 { 2124 Rectangle aVisRect(GetBoundingBox()); 2125 2126 Point aPoint(mpViewShell->GetViewData()->GetPixPos(meSplitPos)); // returns a negative Point 2127 aPoint.setX(-aPoint.getX()); 2128 aPoint.setY(-aPoint.getY()); 2129 aVisRect.SetPos(aPoint); 2130 2131 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 2132 if (pWin) 2133 aVisRect = pWin->PixelToLogic(aVisRect, pWin->GetDrawMapMode()); 2134 2135 return aVisRect; 2136 } 2137 2138 Rectangle ScAccessibleDocument::GetVisibleArea() const 2139 { 2140 ScUnoGuard aGuard; 2141 IsObjectValid(); 2142 return maVisArea; 2143 } 2144 2145 Point ScAccessibleDocument::LogicToPixel (const Point& rPoint) const 2146 { 2147 ScUnoGuard aGuard; 2148 IsObjectValid(); 2149 Point aPoint; 2150 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 2151 if (pWin) 2152 { 2153 aPoint = pWin->LogicToPixel(rPoint, pWin->GetDrawMapMode()); 2154 aPoint += pWin->GetWindowExtentsRelative(NULL).TopLeft(); 2155 } 2156 return aPoint; 2157 } 2158 2159 Size ScAccessibleDocument::LogicToPixel (const Size& rSize) const 2160 { 2161 ScUnoGuard aGuard; 2162 IsObjectValid(); 2163 Size aSize; 2164 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 2165 if (pWin) 2166 aSize = pWin->LogicToPixel(rSize, pWin->GetDrawMapMode()); 2167 return aSize; 2168 } 2169 2170 Point ScAccessibleDocument::PixelToLogic (const Point& rPoint) const 2171 { 2172 ScUnoGuard aGuard; 2173 IsObjectValid(); 2174 Point aPoint; 2175 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 2176 if (pWin) 2177 { 2178 aPoint -= pWin->GetWindowExtentsRelative(NULL).TopLeft(); 2179 aPoint = pWin->PixelToLogic(rPoint, pWin->GetDrawMapMode()); 2180 } 2181 return aPoint; 2182 } 2183 2184 Size ScAccessibleDocument::PixelToLogic (const Size& rSize) const 2185 { 2186 ScUnoGuard aGuard; 2187 IsObjectValid(); 2188 Size aSize; 2189 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); 2190 if (pWin) 2191 aSize = pWin->PixelToLogic(rSize, pWin->GetDrawMapMode()); 2192 return aSize; 2193 } 2194 2195 //===== internal ======================================================== 2196 2197 utl::AccessibleRelationSetHelper* ScAccessibleDocument::GetRelationSet(const ScAddress* pAddress) const 2198 { 2199 utl::AccessibleRelationSetHelper* pRelationSet = NULL; 2200 if (mpChildrenShapes) 2201 pRelationSet = mpChildrenShapes->GetRelationSet(pAddress); 2202 return pRelationSet; 2203 } 2204 2205 ::rtl::OUString SAL_CALL 2206 ScAccessibleDocument::createAccessibleDescription(void) 2207 throw (uno::RuntimeException) 2208 { 2209 rtl::OUString sDescription = String(ScResId(STR_ACC_DOC_DESCR)); 2210 return sDescription; 2211 } 2212 2213 ::rtl::OUString SAL_CALL 2214 ScAccessibleDocument::createAccessibleName(void) 2215 throw (uno::RuntimeException) 2216 { 2217 ScUnoGuard aGuard; 2218 IsObjectValid(); 2219 rtl::OUString sName = String(ScResId(STR_ACC_DOC_NAME)); 2220 sal_Int32 nNumber(sal_Int32(meSplitPos) + 1); 2221 sName += rtl::OUString::valueOf(nNumber); 2222 return sName; 2223 } 2224 2225 Rectangle ScAccessibleDocument::GetBoundingBoxOnScreen() const 2226 throw (uno::RuntimeException) 2227 { 2228 Rectangle aRect; 2229 if (mpViewShell) 2230 { 2231 Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos); 2232 if (pWindow) 2233 aRect = pWindow->GetWindowExtentsRelative(NULL); 2234 } 2235 return aRect; 2236 } 2237 2238 Rectangle ScAccessibleDocument::GetBoundingBox() const 2239 throw (uno::RuntimeException) 2240 { 2241 Rectangle aRect; 2242 if (mpViewShell) 2243 { 2244 Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos); 2245 if (pWindow) 2246 aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow()); 2247 } 2248 return aRect; 2249 } 2250 2251 SCTAB ScAccessibleDocument::getVisibleTable() const 2252 { 2253 SCTAB nVisibleTable(0); 2254 if (mpViewShell && mpViewShell->GetViewData()) 2255 nVisibleTable = mpViewShell->GetViewData()->GetTabNo(); 2256 return nVisibleTable; 2257 } 2258 2259 uno::Reference < XAccessible > 2260 ScAccessibleDocument::GetAccessibleSpreadsheet() 2261 { 2262 if (!mpAccessibleSpreadsheet && mpViewShell) 2263 { 2264 mpAccessibleSpreadsheet = new ScAccessibleSpreadsheet(this, mpViewShell, getVisibleTable(), meSplitPos); 2265 mpAccessibleSpreadsheet->acquire(); 2266 mpAccessibleSpreadsheet->Init(); 2267 mbCompleteSheetSelected = IsTableSelected(); 2268 } 2269 return mpAccessibleSpreadsheet; 2270 } 2271 2272 void ScAccessibleDocument::FreeAccessibleSpreadsheet() 2273 { 2274 if (mpAccessibleSpreadsheet) 2275 { 2276 mpAccessibleSpreadsheet->dispose(); 2277 mpAccessibleSpreadsheet->release(); 2278 mpAccessibleSpreadsheet = NULL; 2279 } 2280 } 2281 2282 sal_Bool ScAccessibleDocument::IsTableSelected() const 2283 { 2284 sal_Bool bResult (sal_False); 2285 if(mpViewShell) 2286 { 2287 SCTAB nTab(getVisibleTable()); 2288 //#103800#; use a copy of MarkData 2289 ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData()); 2290 aMarkData.MarkToMulti(); 2291 if (aMarkData.IsAllMarked(ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab)))) 2292 bResult = sal_True; 2293 } 2294 return bResult; 2295 } 2296 2297 sal_Bool ScAccessibleDocument::IsDefunc( 2298 const uno::Reference<XAccessibleStateSet>& rxParentStates) 2299 { 2300 return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() || 2301 (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC)); 2302 } 2303 2304 sal_Bool ScAccessibleDocument::IsEditable( 2305 const uno::Reference<XAccessibleStateSet>& /* rxParentStates */) 2306 { 2307 // what is with document protection or readonly documents? 2308 return sal_True; 2309 } 2310 2311 void ScAccessibleDocument::AddChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent) 2312 { 2313 DBG_ASSERT(!mxTempAcc.is(), "this object should be removed before"); 2314 if (xAcc.is()) 2315 { 2316 mxTempAcc = xAcc; 2317 if( bFireEvent ) 2318 { 2319 AccessibleEventObject aEvent; 2320 aEvent.Source = uno::Reference<XAccessibleContext>(this); 2321 aEvent.EventId = AccessibleEventId::CHILD; 2322 aEvent.NewValue <<= mxTempAcc; 2323 CommitChange( aEvent ); 2324 } 2325 } 2326 } 2327 2328 void ScAccessibleDocument::RemoveChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent) 2329 { 2330 DBG_ASSERT(mxTempAcc.is(), "this object should be added before"); 2331 if (xAcc.is()) 2332 { 2333 DBG_ASSERT(xAcc.get() == mxTempAcc.get(), "only the same object should be removed"); 2334 if( bFireEvent ) 2335 { 2336 AccessibleEventObject aEvent; 2337 aEvent.Source = uno::Reference<XAccessibleContext>(this); 2338 aEvent.EventId = AccessibleEventId::CHILD; 2339 aEvent.OldValue <<= mxTempAcc; 2340 CommitChange( aEvent ); 2341 } 2342 mxTempAcc = NULL; 2343 } 2344 } 2345 2346 rtl::OUString ScAccessibleDocument::GetCurrentCellName() const 2347 { 2348 String sName( ScResId(STR_ACC_CELL_NAME) ); 2349 if (mpViewShell) 2350 { 2351 String sAddress; 2352 // Document not needed, because only the cell address, but not the tablename is needed 2353 mpViewShell->GetViewData()->GetCurPos().Format( sAddress, SCA_VALID, NULL ); 2354 sName.SearchAndReplaceAscii("%1", sAddress); 2355 } 2356 return rtl::OUString(sName); 2357 } 2358 2359 rtl::OUString ScAccessibleDocument::GetCurrentCellDescription() const 2360 { 2361 return rtl::OUString(); 2362 } 2363 ScDocument *ScAccessibleDocument::GetDocument() const 2364 { 2365 return mpViewShell ? mpViewShell->GetViewData()->GetDocument() : NULL; 2366 } 2367 ScAddress ScAccessibleDocument::GetCurCellAddress() const 2368 { 2369 return mpViewShell ? mpViewShell->GetViewData()->GetCurPos() :ScAddress(); 2370 } 2371 uno::Any SAL_CALL ScAccessibleDocument::getExtendedAttributes() 2372 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 2373 { 2374 2375 uno::Any anyAtrribute; 2376 2377 rtl::OUString sName; 2378 rtl::OUString sValue; 2379 sal_uInt16 sheetIndex; 2380 String sSheetName; 2381 sheetIndex = getVisibleTable(); 2382 if(GetDocument()==NULL) 2383 return anyAtrribute; 2384 GetDocument()->GetName(sheetIndex,sSheetName); 2385 sName = rtl::OUString::createFromAscii("page-name:"); 2386 sValue = sName + sSheetName ; 2387 sName = rtl::OUString::createFromAscii(";page-number:"); 2388 sValue += sName; 2389 sValue += String::CreateFromInt32(sheetIndex+1) ; 2390 sName = rtl::OUString::createFromAscii(";total-pages:"); 2391 sValue += sName; 2392 sValue += String::CreateFromInt32(GetDocument()->GetTableCount()); 2393 sValue += rtl::OUString::createFromAscii(";"); 2394 anyAtrribute <<= sValue; 2395 return anyAtrribute; 2396 } 2397 com::sun::star::uno::Sequence< com::sun::star::uno::Any > ScAccessibleDocument::GetScAccFlowToSequence() 2398 { 2399 if ( getAccessibleChildCount() ) 2400 { 2401 uno::Reference < XAccessible > xSCTableAcc = getAccessibleChild( 0 ); // table 2402 if ( xSCTableAcc.is() ) 2403 { 2404 uno::Reference < XAccessibleSelection > xAccSelection( xSCTableAcc, uno::UNO_QUERY ); 2405 sal_Int32 nSelCount = xAccSelection->getSelectedAccessibleChildCount(); 2406 if( nSelCount ) 2407 { 2408 uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 ); // selected cell 2409 if ( xSel.is() ) 2410 { 2411 uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() ); 2412 if ( xSelContext.is() ) 2413 { 2414 if ( xSelContext->getAccessibleRole() == AccessibleRole::TABLE_CELL ) 2415 { 2416 sal_Int32 nParaCount = 0; 2417 uno::Sequence <uno::Any> aSequence(nSelCount); 2418 for ( sal_Int32 i = 0; i < nSelCount; i++ ) 2419 { 2420 xSel = xAccSelection->getSelectedAccessibleChild( i ) ; 2421 if ( xSel.is() ) 2422 { 2423 xSelContext = xSel->getAccessibleContext(); 2424 if ( xSelContext.is() ) 2425 { 2426 if ( xSelContext->getAccessibleRole() == AccessibleRole::TABLE_CELL ) 2427 { 2428 aSequence[nParaCount] = uno::makeAny( xSel ); 2429 nParaCount++; 2430 } 2431 } 2432 } 2433 } 2434 return aSequence; 2435 } 2436 } 2437 } 2438 } 2439 } 2440 } 2441 uno::Sequence <uno::Any> aEmpty; 2442 return aEmpty; 2443 } 2444 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > 2445 SAL_CALL ScAccessibleDocument::get_AccFlowTo(const ::com::sun::star::uno::Any& rAny, sal_Int32 nType) 2446 throw ( ::com::sun::star::uno::RuntimeException ) 2447 { 2448 const sal_Int32 SPELLCHECKFLOWTO = 1; 2449 const sal_Int32 FINDREPLACEFLOWTO = 2; 2450 if ( nType == SPELLCHECKFLOWTO ) 2451 { 2452 uno::Reference< ::com::sun::star::drawing::XShape > xShape; 2453 rAny >>= xShape; 2454 if ( xShape.is() ) 2455 { 2456 uno::Reference < XAccessible > xAcc = mpChildrenShapes->GetAccessibleCaption(xShape); 2457 uno::Reference < XAccessibleSelection > xAccSelection( xAcc, uno::UNO_QUERY ); 2458 if ( xAccSelection.is() ) 2459 { 2460 if ( xAccSelection->getSelectedAccessibleChildCount() ) 2461 { 2462 uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 ); 2463 if ( xSel.is() ) 2464 { 2465 uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() ); 2466 if ( xSelContext.is() ) 2467 { 2468 //if in sw we find the selected paragraph here 2469 if ( xSelContext->getAccessibleRole() == AccessibleRole::PARAGRAPH ) 2470 { 2471 uno::Sequence<uno::Any> aRet( 1 ); 2472 aRet[0] = uno::makeAny( xSel ); 2473 return aRet; 2474 } 2475 } 2476 } 2477 } 2478 } 2479 } 2480 else 2481 { 2482 if ( getSelectedAccessibleChildCount() ) 2483 { 2484 uno::Reference < XAccessible > xSel = getSelectedAccessibleChild( 0 ); 2485 if ( xSel.is() ) 2486 { 2487 uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() ); 2488 if ( xSelContext.is() ) 2489 { 2490 uno::Reference < XAccessibleSelection > xAccChildSelection( xSel, uno::UNO_QUERY ); 2491 if ( xAccChildSelection.is() ) 2492 { 2493 if ( xAccChildSelection->getSelectedAccessibleChildCount() ) 2494 { 2495 uno::Reference < XAccessible > xChildSel = xAccChildSelection->getSelectedAccessibleChild( 0 ); 2496 if ( xChildSel.is() ) 2497 { 2498 uno::Reference < ::com::sun::star::accessibility::XAccessibleContext > xChildSelContext( xChildSel->getAccessibleContext() ); 2499 if ( xChildSelContext.is() && 2500 xChildSelContext->getAccessibleRole() == ::com::sun::star::accessibility::AccessibleRole::PARAGRAPH ) 2501 { 2502 uno::Sequence<uno::Any> aRet( 1 ); 2503 aRet[0] = uno::makeAny( xChildSel ); 2504 return aRet; 2505 } 2506 } 2507 } 2508 } 2509 } 2510 } 2511 } 2512 } 2513 } 2514 else if ( nType == FINDREPLACEFLOWTO ) 2515 { 2516 sal_Bool bSuccess(sal_False); 2517 rAny >>= bSuccess; 2518 if ( bSuccess ) 2519 { 2520 uno::Sequence< uno::Any> aSeq = GetScAccFlowToSequence(); 2521 if ( aSeq.getLength() ) 2522 { 2523 return aSeq; 2524 } 2525 else if( mpAccessibleSpreadsheet ) 2526 { 2527 uno::Reference < XAccessible > xFindCellAcc = mpAccessibleSpreadsheet->GetActiveCell(); 2528 // add xFindCellAcc to the return the Sequence 2529 uno::Sequence< uno::Any> aSeq2(1); 2530 aSeq2[0] = uno::makeAny( xFindCellAcc ); 2531 return aSeq2; 2532 } 2533 } 2534 } 2535 uno::Sequence< uno::Any> aEmpty; 2536 return aEmpty; 2537 } 2538 void ScAccessibleDocument::SwitchViewFireFocus() 2539 { 2540 if (mpAccessibleSpreadsheet) 2541 { 2542 mpAccessibleSpreadsheet->FireFirstCellFocus(); 2543 } 2544 } 2545 2546 sal_Int32 SAL_CALL ScAccessibleDocument::getForeground( ) 2547 throw (uno::RuntimeException) 2548 { 2549 return COL_BLACK; 2550 } 2551 2552 sal_Int32 SAL_CALL ScAccessibleDocument::getBackground( ) 2553 throw (uno::RuntimeException) 2554 { 2555 ScUnoGuard aGuard; 2556 IsObjectValid(); 2557 return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor; 2558 } 2559 2560