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