1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sc.hxx" 30 31 #include "AccessibleDocumentPagePreview.hxx" 32 #include "AccessiblePreviewTable.hxx" 33 #include "AccessiblePageHeader.hxx" 34 #include "AccessibilityHints.hxx" 35 #include "AccessibleText.hxx" 36 #include "document.hxx" 37 #include "prevwsh.hxx" 38 #include "prevloc.hxx" 39 #include "unoguard.hxx" 40 #include "drwlayer.hxx" 41 #include "editsrc.hxx" 42 #include "scresid.hxx" 43 #include "sc.hrc" 44 #include "DrawModelBroadcaster.hxx" 45 #include "docsh.hxx" 46 #include "drawview.hxx" 47 #include "preview.hxx" 48 #include "postit.hxx" 49 50 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 51 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 52 #include <com/sun/star/accessibility/AccessibleRelationType.hpp> 53 54 #include <unotools/accessiblestatesethelper.hxx> 55 #include <tools/debug.hxx> 56 #include <tools/gen.hxx> 57 #include <svx/svdpage.hxx> 58 #include <svx/svdobj.hxx> 59 #include <svx/AccessibleTextHelper.hxx> 60 #include <svx/AccessibleShape.hxx> 61 #include <svx/ShapeTypeHandler.hxx> 62 #include <toolkit/helper/convert.hxx> 63 #include <svx/unoshape.hxx> 64 #include <unotools/accessiblerelationsethelper.hxx> 65 66 #include <vector> 67 #include <list> 68 #include <algorithm> 69 #include <memory> 70 71 using namespace ::com::sun::star; 72 using namespace ::com::sun::star::accessibility; 73 74 //========================================================================= 75 76 typedef std::list< uno::Reference< XAccessible > > ScXAccList; 77 78 79 struct ScAccNote 80 { 81 String maNoteText; 82 Rectangle maRect; 83 ScAddress maNoteCell; 84 ::accessibility::AccessibleTextHelper* mpTextHelper; 85 sal_Int32 mnParaCount; 86 sal_Bool mbMarkNote; 87 88 ScAccNote() : mpTextHelper(NULL), mnParaCount(0) {} 89 }; 90 91 class ScNotesChilds 92 { 93 public: 94 ScNotesChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc); 95 ~ScNotesChilds(); 96 void Init(const Rectangle& rVisRect, sal_Int32 nOffset); 97 98 sal_Int32 GetChildsCount() const; 99 uno::Reference<XAccessible> GetChild(sal_Int32 nIndex) const; 100 uno::Reference<XAccessible> GetAt(const awt::Point& rPoint) const; 101 102 void DataChanged(const Rectangle& rVisRect); 103 void SetOffset(sal_Int32 nNewOffset); 104 private: 105 ScPreviewShell* mpViewShell; 106 ScAccessibleDocumentPagePreview* mpAccDoc; 107 typedef std::vector<ScAccNote> ScAccNotes; 108 mutable ScAccNotes maNotes; 109 mutable ScAccNotes maMarks; 110 sal_Int32 mnParagraphs; 111 sal_Int32 mnOffset; 112 113 ::accessibility::AccessibleTextHelper* CreateTextHelper(const String& rString, const Rectangle& rVisRect, const ScAddress& aCellPos, sal_Bool bMarkNote, sal_Int32 nChildOffset) const; 114 sal_Int32 AddNotes(const ScPreviewLocationData& rData, const Rectangle& rVisRect, sal_Bool bMark, ScAccNotes& rNotes); 115 116 sal_Int8 CompareCell(const ScAddress& aCell1, const ScAddress& aCell2); 117 void CollectChilds(const ScAccNote& rNote, ScXAccList& rList); 118 sal_Int32 CheckChanges(const ScPreviewLocationData& rData, const Rectangle& rVisRect, 119 sal_Bool bMark, ScAccNotes& rOldNotes, ScAccNotes& rNewNotes, 120 ScXAccList& rOldParas, ScXAccList& rNewParas); 121 122 inline ScDocument* GetDocument() const; 123 }; 124 125 ScNotesChilds::ScNotesChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc) 126 : mpViewShell(pViewShell), 127 mpAccDoc(pAccDoc), 128 mnParagraphs(0), 129 mnOffset(0) 130 { 131 } 132 133 struct DeleteAccNote 134 { 135 void operator()(ScAccNote& rNote) 136 { 137 if (rNote.mpTextHelper) 138 DELETEZ( rNote.mpTextHelper); 139 } 140 }; 141 142 ScNotesChilds::~ScNotesChilds() 143 { 144 std::for_each(maNotes.begin(), maNotes.end(), DeleteAccNote()); 145 std::for_each(maMarks.begin(), maMarks.end(), DeleteAccNote()); 146 } 147 148 ::accessibility::AccessibleTextHelper* ScNotesChilds::CreateTextHelper(const String& rString, const Rectangle& rVisRect, const ScAddress& aCellPos, sal_Bool bMarkNote, sal_Int32 nChildOffset) const 149 { 150 ::accessibility::AccessibleTextHelper* pTextHelper = NULL; 151 152 ::std::auto_ptr < ScAccessibleTextData > pAccessiblePreviewHeaderCellTextData 153 (new ScAccessibleNoteTextData(mpViewShell, rString, aCellPos, bMarkNote)); 154 ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessiblePreviewHeaderCellTextData)); 155 156 pTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource); 157 158 if (pTextHelper) 159 { 160 pTextHelper->SetEventSource(mpAccDoc); 161 pTextHelper->SetStartIndex(nChildOffset); 162 pTextHelper->SetOffset(rVisRect.TopLeft()); 163 } 164 165 return pTextHelper; 166 } 167 168 sal_Int32 ScNotesChilds::AddNotes(const ScPreviewLocationData& rData, const Rectangle& rVisRect, sal_Bool bMark, ScAccNotes& rNotes) 169 { 170 sal_Int32 nCount = rData.GetNoteCountInRange(rVisRect, bMark); 171 172 rNotes.reserve(nCount); 173 174 sal_Int32 nParagraphs(0); 175 ScDocument* pDoc = GetDocument(); 176 if (pDoc) 177 { 178 ScAccNote aNote; 179 aNote.mbMarkNote = bMark; 180 if (bMark) 181 aNote.mnParaCount = 1; 182 for (sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex) 183 { 184 if (rData.GetNoteInRange(rVisRect, nIndex, bMark, aNote.maNoteCell, aNote.maRect)) 185 { 186 if (bMark) 187 { 188 // Document not needed, because only the cell address, but not the tablename is needed 189 aNote.maNoteCell.Format( aNote.maNoteText, SCA_VALID, NULL ); 190 } 191 else 192 { 193 if( ScPostIt* pNote = pDoc->GetNote( aNote.maNoteCell ) ) 194 aNote.maNoteText = pNote->GetText(); 195 aNote.mpTextHelper = CreateTextHelper(aNote.maNoteText, aNote.maRect, aNote.maNoteCell, aNote.mbMarkNote, nParagraphs + mnOffset); 196 if (aNote.mpTextHelper) 197 aNote.mnParaCount = aNote.mpTextHelper->GetChildCount(); 198 } 199 nParagraphs += aNote.mnParaCount; 200 rNotes.push_back(aNote); 201 } 202 } 203 } 204 return nParagraphs; 205 } 206 207 void ScNotesChilds::Init(const Rectangle& rVisRect, sal_Int32 nOffset) 208 { 209 if (mpViewShell && !mnParagraphs) 210 { 211 mnOffset = nOffset; 212 const ScPreviewLocationData& rData = mpViewShell->GetLocationData(); 213 214 mnParagraphs = AddNotes(rData, rVisRect, sal_False, maMarks); 215 mnParagraphs += AddNotes(rData, rVisRect, sal_True, maNotes); 216 } 217 } 218 219 sal_Int32 ScNotesChilds::GetChildsCount() const 220 { 221 return mnParagraphs; 222 } 223 224 struct ScParaFound 225 { 226 sal_Int32 mnIndex; 227 ScParaFound(sal_Int32 nIndex) : mnIndex(nIndex) {} 228 sal_Bool operator() (const ScAccNote& rNote) 229 { 230 sal_Bool bResult(sal_False); 231 if (rNote.mnParaCount > mnIndex) 232 bResult = sal_True; 233 else 234 mnIndex -= rNote.mnParaCount; 235 return bResult; 236 } 237 }; 238 239 uno::Reference<XAccessible> ScNotesChilds::GetChild(sal_Int32 nIndex) const 240 { 241 uno::Reference<XAccessible> xAccessible; 242 243 if (nIndex < mnParagraphs) 244 { 245 if (nIndex < static_cast<sal_Int32>(maMarks.size())) 246 { 247 ScAccNotes::iterator aEndItr = maMarks.end(); 248 ScParaFound aParaFound(nIndex); 249 ScAccNotes::iterator aItr = std::find_if(maMarks.begin(), aEndItr, aParaFound); 250 if (aItr != aEndItr) 251 { 252 DBG_ASSERT((aItr->maNoteCell == maMarks[nIndex].maNoteCell) && (aItr->mbMarkNote == maMarks[nIndex].mbMarkNote), "wrong note found"); 253 } 254 else 255 { 256 DBG_ERRORFILE("wrong note found"); 257 } 258 if (!aItr->mpTextHelper) 259 aItr->mpTextHelper = CreateTextHelper(maMarks[nIndex].maNoteText, maMarks[nIndex].maRect, maMarks[nIndex].maNoteCell, maMarks[nIndex].mbMarkNote, nIndex + mnOffset); // the marks are the first and every mark has only one paragraph 260 xAccessible = aItr->mpTextHelper->GetChild(aParaFound.mnIndex + aItr->mpTextHelper->GetStartIndex()); 261 } 262 else 263 { 264 nIndex -= maMarks.size(); 265 ScAccNotes::iterator aEndItr = maNotes.end(); 266 ScParaFound aParaFound(nIndex); 267 ScAccNotes::iterator aItr = std::find_if(maNotes.begin(), aEndItr, aParaFound); 268 if (aEndItr != aItr) 269 { 270 if (!aItr->mpTextHelper) 271 aItr->mpTextHelper = CreateTextHelper(aItr->maNoteText, aItr->maRect, aItr->maNoteCell, aItr->mbMarkNote, (nIndex - aParaFound.mnIndex) + mnOffset + maMarks.size()); 272 xAccessible = aItr->mpTextHelper->GetChild(aParaFound.mnIndex + aItr->mpTextHelper->GetStartIndex()); 273 } 274 } 275 } 276 277 return xAccessible; 278 } 279 280 struct ScPointFound 281 { 282 Rectangle maPoint; 283 sal_Int32 mnParagraphs; 284 ScPointFound(const Point& rPoint) : maPoint(rPoint, Size(0, 0)), mnParagraphs(0) {} 285 sal_Bool operator() (const ScAccNote& rNote) 286 { 287 sal_Bool bResult(sal_False); 288 if (maPoint.IsInside(rNote.maRect)) 289 bResult = sal_True; 290 else 291 mnParagraphs += rNote.mnParaCount; 292 return bResult; 293 } 294 }; 295 296 uno::Reference<XAccessible> ScNotesChilds::GetAt(const awt::Point& rPoint) const 297 { 298 uno::Reference<XAccessible> xAccessible; 299 300 ScPointFound aPointFound(Point(rPoint.X, rPoint.Y)); 301 302 ScAccNotes::iterator aEndItr = maMarks.end(); 303 ScAccNotes::iterator aItr = std::find_if(maMarks.begin(), aEndItr, aPointFound); 304 if (aEndItr == aItr) 305 { 306 aEndItr = maNotes.end(); 307 aItr = std::find_if(maNotes.begin(), aEndItr, aPointFound); 308 } 309 if (aEndItr != aItr) 310 { 311 if (!aItr->mpTextHelper) 312 aItr->mpTextHelper = CreateTextHelper(aItr->maNoteText, aItr->maRect, aItr->maNoteCell, aItr->mbMarkNote, aPointFound.mnParagraphs + mnOffset); 313 xAccessible = aItr->mpTextHelper->GetAt(rPoint); 314 } 315 316 return xAccessible; 317 } 318 319 sal_Int8 ScNotesChilds::CompareCell(const ScAddress& aCell1, const ScAddress& aCell2) 320 { 321 DBG_ASSERT(aCell1.Tab() == aCell2.Tab(), "the notes should be on the same table"); 322 sal_Int8 nResult(0); 323 if (aCell1 != aCell2) 324 { 325 if (aCell1.Row() == aCell2.Row()) 326 nResult = (aCell1.Col() < aCell2.Col()) ? -1 : 1; 327 else 328 nResult = (aCell1.Row() < aCell2.Row()) ? -1 : 1; 329 } 330 return nResult; 331 } 332 333 void ScNotesChilds::CollectChilds(const ScAccNote& rNote, ScXAccList& rList) 334 { 335 if (rNote.mpTextHelper) 336 for (sal_Int32 i = 0; i < rNote.mnParaCount; ++i) 337 rList.push_back(rNote.mpTextHelper->GetChild(i + rNote.mpTextHelper->GetStartIndex())); 338 } 339 340 sal_Int32 ScNotesChilds::CheckChanges(const ScPreviewLocationData& rData, 341 const Rectangle& rVisRect, sal_Bool bMark, ScAccNotes& rOldNotes, 342 ScAccNotes& rNewNotes, ScXAccList& rOldParas, ScXAccList& rNewParas) 343 { 344 sal_Int32 nCount = rData.GetNoteCountInRange(rVisRect, bMark); 345 346 rNewNotes.reserve(nCount); 347 348 sal_Int32 nParagraphs(0); 349 ScDocument* pDoc = GetDocument(); 350 if (pDoc) 351 { 352 ScAccNote aNote; 353 aNote.mbMarkNote = bMark; 354 if (bMark) 355 aNote.mnParaCount = 1; 356 ScAccNotes::iterator aItr = rOldNotes.begin(); 357 ScAccNotes::iterator aEndItr = rOldNotes.end(); 358 sal_Bool bAddNote(sal_False); 359 for (sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex) 360 { 361 if (rData.GetNoteInRange(rVisRect, nIndex, bMark, aNote.maNoteCell, aNote.maRect)) 362 { 363 if (bMark) 364 { 365 // Document not needed, because only the cell address, but not the tablename is needed 366 aNote.maNoteCell.Format( aNote.maNoteText, SCA_VALID, NULL ); 367 } 368 else 369 { 370 if( ScPostIt* pNote = pDoc->GetNote( aNote.maNoteCell ) ) 371 aNote.maNoteText = pNote->GetText(); 372 } 373 374 sal_Int8 nCompare(-1); // if there are no more old childs it is always a new one 375 if (aItr != aEndItr) 376 nCompare = CompareCell(aNote.maNoteCell, aItr->maNoteCell); 377 if (nCompare == 0) 378 { 379 if (aNote.maNoteText == aItr->maNoteText) 380 { 381 aNote.mpTextHelper = aItr->mpTextHelper; 382 if (aNote.maRect != aItr->maRect) //neue VisArea setzen 383 { 384 aNote.mpTextHelper->SetOffset(aNote.maRect.TopLeft()); 385 aNote.mpTextHelper->UpdateChildren(); 386 //DBG_ASSERT(aItr->maRect.GetSize() == aNote.maRect.GetSize(), "size should be the same, because the text is not changed"); 387 // could be changed, because only a part of the note is visible 388 } 389 } 390 else 391 { 392 aNote.mpTextHelper = CreateTextHelper(aNote.maNoteText, aNote.maRect, aNote.maNoteCell, aNote.mbMarkNote, nParagraphs + mnOffset); 393 if (aNote.mpTextHelper) 394 aNote.mnParaCount = aNote.mpTextHelper->GetChildCount(); 395 // collect removed childs 396 CollectChilds(*aItr, rOldParas); 397 DELETEZ(aItr->mpTextHelper); 398 // collect new childs 399 CollectChilds(aNote, rNewParas); 400 } 401 bAddNote = sal_True; 402 // not necessary, because this branch should not be reached if it is the end 403 //if (aItr != aEndItr) 404 ++aItr; 405 } 406 else if (nCompare < 0) 407 { 408 aNote.mpTextHelper = CreateTextHelper(aNote.maNoteText, aNote.maRect, aNote.maNoteCell, aNote.mbMarkNote, nParagraphs + mnOffset); 409 if (aNote.mpTextHelper) 410 aNote.mnParaCount = aNote.mpTextHelper->GetChildCount(); 411 // collect new childs 412 CollectChilds(aNote, rNewParas); 413 bAddNote = sal_True; 414 } 415 else 416 { 417 // collect removed childs 418 CollectChilds(*aItr, rOldParas); 419 DELETEZ(aItr->mpTextHelper); 420 421 // no note to add 422 // not necessary, because this branch should not be reached if it is the end 423 //if (aItr != aEndItr) 424 ++aItr; 425 } 426 if (bAddNote) 427 { 428 nParagraphs += aNote.mnParaCount; 429 rNewNotes.push_back(aNote); 430 bAddNote = sal_False; 431 } 432 } 433 } 434 } 435 return nParagraphs; 436 } 437 438 struct ScChildGone 439 { 440 ScAccessibleDocumentPagePreview* mpAccDoc; 441 ScChildGone(ScAccessibleDocumentPagePreview* pAccDoc) : mpAccDoc(pAccDoc) {} 442 void operator() (const uno::Reference<XAccessible>& xAccessible) const 443 { 444 if (mpAccDoc) 445 { 446 AccessibleEventObject aEvent; 447 aEvent.EventId = AccessibleEventId::CHILD; 448 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccDoc); 449 aEvent.OldValue <<= xAccessible; 450 451 mpAccDoc->CommitChange(aEvent); // gone child - event 452 } 453 } 454 }; 455 456 struct ScChildNew 457 { 458 ScAccessibleDocumentPagePreview* mpAccDoc; 459 ScChildNew(ScAccessibleDocumentPagePreview* pAccDoc) : mpAccDoc(pAccDoc) {} 460 void operator() (const uno::Reference<XAccessible>& xAccessible) const 461 { 462 if (mpAccDoc) 463 { 464 AccessibleEventObject aEvent; 465 aEvent.EventId = AccessibleEventId::CHILD; 466 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccDoc); 467 aEvent.NewValue <<= xAccessible; 468 469 mpAccDoc->CommitChange(aEvent); // new child - event 470 } 471 } 472 }; 473 474 void ScNotesChilds::DataChanged(const Rectangle& rVisRect) 475 { 476 if (mpViewShell && mpAccDoc) 477 { 478 ScXAccList aNewParas; 479 ScXAccList aOldParas; 480 ScAccNotes aNewMarks; 481 mnParagraphs = CheckChanges(mpViewShell->GetLocationData(), rVisRect, sal_True, maMarks, aNewMarks, aOldParas, aNewParas); 482 maMarks = aNewMarks; 483 ScAccNotes aNewNotes; 484 mnParagraphs += CheckChanges(mpViewShell->GetLocationData(), rVisRect, sal_False, maNotes, aNewNotes, aOldParas, aNewParas); 485 maNotes = aNewNotes; 486 487 std::for_each(aOldParas.begin(), aOldParas.end(), ScChildGone(mpAccDoc)); 488 std::for_each(aNewParas.begin(), aNewParas.end(), ScChildNew(mpAccDoc)); 489 } 490 } 491 492 struct ScChangeOffset 493 { 494 sal_Int32 mnDiff; 495 ScChangeOffset(sal_Int32 nDiff) : mnDiff(nDiff) {} 496 void operator() (const ScAccNote& rNote) 497 { 498 if (rNote.mpTextHelper) 499 rNote.mpTextHelper->SetStartIndex(rNote.mpTextHelper->GetStartIndex() + mnDiff); 500 } 501 }; 502 503 void ScNotesChilds::SetOffset(sal_Int32 nNewOffset) 504 { 505 sal_Int32 nDiff(nNewOffset - mnOffset); 506 if (nDiff != 0) 507 { 508 std::for_each(maMarks.begin(), maMarks.end(), ScChangeOffset(nDiff)); 509 std::for_each(maNotes.begin(), maNotes.end(), ScChangeOffset(nDiff)); 510 mnOffset = nNewOffset; 511 } 512 } 513 514 inline ScDocument* ScNotesChilds::GetDocument() const 515 { 516 ScDocument* pDoc = NULL; 517 if (mpViewShell) 518 pDoc = mpViewShell->GetDocument(); 519 return pDoc; 520 } 521 522 class ScIAccessibleViewForwarder : public ::accessibility::IAccessibleViewForwarder 523 { 524 public: 525 ScIAccessibleViewForwarder(); 526 ScIAccessibleViewForwarder(ScPreviewShell* pViewShell, 527 ScAccessibleDocumentPagePreview* pAccDoc, 528 const MapMode& aMapMode); 529 ~ScIAccessibleViewForwarder(); 530 531 ///===== IAccessibleViewForwarder ======================================== 532 533 virtual sal_Bool IsValid (void) const; 534 virtual Rectangle GetVisibleArea() const; 535 virtual Point LogicToPixel (const Point& rPoint) const; 536 virtual Size LogicToPixel (const Size& rSize) const; 537 virtual Point PixelToLogic (const Point& rPoint) const; 538 virtual Size PixelToLogic (const Size& rSize) const; 539 540 private: 541 ScPreviewShell* mpViewShell; 542 ScAccessibleDocumentPagePreview* mpAccDoc; 543 MapMode maMapMode; 544 sal_Bool mbValid; 545 }; 546 547 ScIAccessibleViewForwarder::ScIAccessibleViewForwarder() 548 : mbValid(sal_False) 549 { 550 } 551 552 ScIAccessibleViewForwarder::ScIAccessibleViewForwarder(ScPreviewShell* pViewShell, 553 ScAccessibleDocumentPagePreview* pAccDoc, 554 const MapMode& aMapMode) 555 : mpViewShell(pViewShell), 556 mpAccDoc(pAccDoc), 557 maMapMode(aMapMode), 558 mbValid(sal_True) 559 { 560 } 561 562 ScIAccessibleViewForwarder::~ScIAccessibleViewForwarder() 563 { 564 } 565 566 ///===== IAccessibleViewForwarder ======================================== 567 568 sal_Bool ScIAccessibleViewForwarder::IsValid (void) const 569 { 570 ScUnoGuard aGuard; 571 return mbValid; 572 } 573 574 Rectangle ScIAccessibleViewForwarder::GetVisibleArea() const 575 { 576 ScUnoGuard aGuard; 577 Rectangle aVisRect; 578 Window* pWin = mpViewShell->GetWindow(); 579 if (pWin) 580 { 581 aVisRect.SetSize(pWin->GetOutputSizePixel()); 582 aVisRect.SetPos(Point(0, 0)); 583 584 aVisRect = pWin->PixelToLogic(aVisRect, maMapMode); 585 } 586 587 return aVisRect; 588 } 589 590 Point ScIAccessibleViewForwarder::LogicToPixel (const Point& rPoint) const 591 { 592 ScUnoGuard aGuard; 593 Point aPoint; 594 Window* pWin = mpViewShell->GetWindow(); 595 if (pWin && mpAccDoc) 596 { 597 Rectangle aRect(mpAccDoc->GetBoundingBoxOnScreen()); 598 aPoint = pWin->LogicToPixel(rPoint, maMapMode) + aRect.TopLeft(); 599 } 600 601 return aPoint; 602 } 603 604 Size ScIAccessibleViewForwarder::LogicToPixel (const Size& rSize) const 605 { 606 ScUnoGuard aGuard; 607 Size aSize; 608 Window* pWin = mpViewShell->GetWindow(); 609 if (pWin) 610 aSize = pWin->LogicToPixel(rSize, maMapMode); 611 return aSize; 612 } 613 614 Point ScIAccessibleViewForwarder::PixelToLogic (const Point& rPoint) const 615 { 616 ScUnoGuard aGuard; 617 Point aPoint; 618 Window* pWin = mpViewShell->GetWindow(); 619 if (pWin && mpAccDoc) 620 { 621 Rectangle aRect(mpAccDoc->GetBoundingBoxOnScreen()); 622 aPoint = pWin->PixelToLogic(rPoint - aRect.TopLeft(), maMapMode); 623 } 624 return aPoint; 625 } 626 627 Size ScIAccessibleViewForwarder::PixelToLogic (const Size& rSize) const 628 { 629 ScUnoGuard aGuard; 630 Size aSize; 631 Window* pWin = mpViewShell->GetWindow(); 632 if (pWin) 633 aSize = pWin->PixelToLogic(rSize, maMapMode); 634 return aSize; 635 } 636 637 struct ScShapeChild 638 { 639 ScShapeChild() : mpAccShape(NULL) {} 640 ScShapeChild(const ScShapeChild& rOld); 641 ~ScShapeChild(); 642 mutable ::accessibility::AccessibleShape* mpAccShape; 643 com::sun::star::uno::Reference< com::sun::star::drawing::XShape > mxShape; 644 sal_Int32 mnRangeId; 645 }; 646 647 ScShapeChild::ScShapeChild(const ScShapeChild& rOld) 648 : 649 mpAccShape(rOld.mpAccShape), 650 mxShape(rOld.mxShape), 651 mnRangeId(rOld.mnRangeId) 652 { 653 if (mpAccShape) 654 mpAccShape->acquire(); 655 } 656 657 ScShapeChild::~ScShapeChild() 658 { 659 if (mpAccShape) 660 { 661 mpAccShape->dispose(); 662 mpAccShape->release(); 663 } 664 } 665 666 struct ScShapeChildLess 667 { 668 sal_Bool operator()(const ScShapeChild& rChild1, const ScShapeChild& rChild2) const 669 { 670 sal_Bool bResult(sal_False); 671 if (rChild1.mxShape.is() && rChild2.mxShape.is()) 672 bResult = (rChild1.mxShape.get() < rChild2.mxShape.get()); 673 return bResult; 674 } 675 }; 676 677 typedef std::vector<ScShapeChild> ScShapeChildVec; 678 679 struct ScShapeRange 680 { 681 ScShapeChildVec maBackShapes; 682 ScShapeChildVec maForeShapes; // inclusive internal shapes 683 ScShapeChildVec maControls; 684 Rectangle maPixelRect; 685 MapMode maMapMode; 686 ScIAccessibleViewForwarder maViewForwarder; 687 }; 688 689 typedef std::vector<ScShapeRange> ScShapeRangeVec; 690 691 class ScShapeChilds : public SfxListener, 692 public ::accessibility::IAccessibleParent 693 { 694 public: 695 ScShapeChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc); 696 ~ScShapeChilds(); 697 698 ///===== SfxListener ===================================================== 699 700 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); 701 702 ///===== IAccessibleParent ============================================== 703 704 virtual sal_Bool ReplaceChild ( 705 ::accessibility::AccessibleShape* pCurrentChild, 706 const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape, 707 const long _nIndex, 708 const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo 709 ) throw (::com::sun::star::uno::RuntimeException); 710 711 ///===== Internal ======================================================== 712 713 void Init(); 714 715 sal_Int32 GetBackShapeCount() const; 716 uno::Reference<XAccessible> GetBackShape(sal_Int32 nIndex) const; 717 sal_Int32 GetForeShapeCount() const; 718 uno::Reference<XAccessible> GetForeShape(sal_Int32 nIndex) const; 719 sal_Int32 GetControlCount() const; 720 uno::Reference<XAccessible> GetControl(sal_Int32 nIndex) const; 721 uno::Reference<XAccessible> GetForegroundShapeAt(const awt::Point& rPoint) const; // inclusive controls 722 uno::Reference<XAccessible> GetBackgroundShapeAt(const awt::Point& rPoint) const; 723 724 void DataChanged(); 725 void VisAreaChanged() const; 726 727 void SetDrawBroadcaster(); 728 private: 729 ScAccessibleDocumentPagePreview* mpAccDoc; 730 ScPreviewShell* mpViewShell; 731 ScShapeRangeVec maShapeRanges; 732 733 void FindChanged(ScShapeChildVec& aOld, ScShapeChildVec& aNew) const; 734 void FindChanged(ScShapeRange& aOld, ScShapeRange& aNew) const; 735 ::accessibility::AccessibleShape* GetAccShape(const ScShapeChild& rShape) const; 736 ::accessibility::AccessibleShape* GetAccShape(const ScShapeChildVec& rShapes, sal_Int32 nIndex) const; 737 void FillShapes(const Rectangle& aPixelPaintRect, const MapMode& aMapMode, sal_uInt8 nRangeId); 738 //UNUSED2008-05 sal_Bool FindShape(ScShapeChildVec& rShapes, const uno::Reference <drawing::XShape>& xShape, ScShapeChildVec::iterator& rItr) const; 739 740 // void AddShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID); 741 // void RemoveShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID); 742 SdrPage* GetDrawPage() const; 743 }; 744 745 ScShapeChilds::ScShapeChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc) 746 : 747 mpAccDoc(pAccDoc), 748 mpViewShell(pViewShell), 749 maShapeRanges(SC_PREVIEW_MAXRANGES) 750 { 751 if (pViewShell) 752 { 753 SfxBroadcaster* pDrawBC = pViewShell->GetDocument()->GetDrawBroadcaster(); 754 if (pDrawBC) 755 StartListening(*pDrawBC); 756 } 757 } 758 759 ScShapeChilds::~ScShapeChilds() 760 { 761 if (mpViewShell) 762 { 763 SfxBroadcaster* pDrawBC = mpViewShell->GetDocument()->GetDrawBroadcaster(); 764 if (pDrawBC) 765 EndListening(*pDrawBC); 766 } 767 } 768 769 void ScShapeChilds::SetDrawBroadcaster() 770 { 771 if (mpViewShell) 772 { 773 SfxBroadcaster* pDrawBC = mpViewShell->GetDocument()->GetDrawBroadcaster(); 774 if (pDrawBC) 775 StartListening(*pDrawBC, sal_True); 776 } 777 } 778 779 void ScShapeChilds::Notify(SfxBroadcaster&, const SfxHint& rHint) 780 { 781 if ( rHint.ISA( SdrHint ) ) 782 { 783 const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint ); 784 if (pSdrHint) 785 { 786 SdrObject* pObj = const_cast<SdrObject*>(pSdrHint->GetObject()); 787 if (pObj && (pObj->GetPage() == GetDrawPage())) 788 { 789 switch (pSdrHint->GetKind()) 790 { 791 case HINT_OBJCHG : // Objekt geaendert 792 { 793 } 794 break; 795 // no longer necessary 796 /* case HINT_OBJINSERTED : // Neues Zeichenobjekt eingefuegt 797 { 798 uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY); 799 if (xShape.is()) 800 AddShape(xShape, pObj->GetLayer()); 801 } 802 break; 803 case HINT_OBJREMOVED : // Zeichenobjekt aus Liste entfernt 804 { 805 uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY); 806 if (xShape.is()) 807 RemoveShape(xShape, pObj->GetLayer()); 808 } 809 break;*/ 810 default : 811 { 812 // other events are not interesting 813 } 814 break; 815 } 816 } 817 } 818 } 819 } 820 821 void ScShapeChilds::FindChanged(ScShapeChildVec& rOld, ScShapeChildVec& rNew) const 822 { 823 ScShapeChildVec::iterator aOldItr = rOld.begin(); 824 ScShapeChildVec::iterator aOldEnd = rOld.end(); 825 ScShapeChildVec::const_iterator aNewItr = rNew.begin(); 826 ScShapeChildVec::const_iterator aNewEnd = rNew.begin(); 827 uno::Reference<XAccessible> xAcc; 828 while ((aNewItr != aNewEnd) && (aOldItr != aOldEnd)) 829 { 830 if (aNewItr->mxShape.get() == aOldItr->mxShape.get()) 831 { 832 ++aOldItr; 833 ++aNewItr; 834 } 835 else if (aNewItr->mxShape.get() < aOldItr->mxShape.get()) 836 { 837 xAcc = GetAccShape(*aNewItr); 838 AccessibleEventObject aEvent; 839 aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc); 840 aEvent.EventId = AccessibleEventId::CHILD; 841 aEvent.NewValue <<= xAcc; 842 mpAccDoc->CommitChange(aEvent); 843 ++aNewItr; 844 } 845 else 846 { 847 xAcc = GetAccShape(*aOldItr); 848 AccessibleEventObject aEvent; 849 aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc); 850 aEvent.EventId = AccessibleEventId::CHILD; 851 aEvent.OldValue <<= xAcc; 852 mpAccDoc->CommitChange(aEvent); 853 ++aOldItr; 854 } 855 } 856 while (aOldItr != aOldEnd) 857 { 858 xAcc = GetAccShape(*aOldItr); 859 AccessibleEventObject aEvent; 860 aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc); 861 aEvent.EventId = AccessibleEventId::CHILD; 862 aEvent.OldValue <<= xAcc; 863 mpAccDoc->CommitChange(aEvent); 864 ++aOldItr; 865 } 866 while (aNewItr != aNewEnd) 867 { 868 xAcc = GetAccShape(*aNewItr); 869 AccessibleEventObject aEvent; 870 aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc); 871 aEvent.EventId = AccessibleEventId::CHILD; 872 aEvent.NewValue <<= xAcc; 873 mpAccDoc->CommitChange(aEvent); 874 ++aNewItr; 875 } 876 } 877 878 void ScShapeChilds::FindChanged(ScShapeRange& rOld, ScShapeRange& rNew) const 879 { 880 FindChanged(rOld.maBackShapes, rNew.maBackShapes); 881 FindChanged(rOld.maForeShapes, rNew.maForeShapes); 882 FindChanged(rOld.maControls, rNew.maControls); 883 } 884 885 void ScShapeChilds::DataChanged() 886 { 887 ScShapeRangeVec aOldShapeRanges(maShapeRanges); 888 maShapeRanges.clear(); 889 maShapeRanges.resize(SC_PREVIEW_MAXRANGES); 890 Init(); 891 for (sal_Int32 i = 0; i < SC_PREVIEW_MAXRANGES; ++i) 892 { 893 FindChanged(aOldShapeRanges[i], maShapeRanges[i]); 894 } 895 } 896 897 struct ScVisAreaChanged 898 { 899 const ScIAccessibleViewForwarder* mpViewForwarder; 900 ScVisAreaChanged(const ScIAccessibleViewForwarder* pViewForwarder) : mpViewForwarder(pViewForwarder) {} 901 void operator() (const ScShapeChild& rAccShapeData) const 902 { 903 if (rAccShapeData.mpAccShape) 904 { 905 rAccShapeData.mpAccShape->ViewForwarderChanged(::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA, mpViewForwarder); 906 } 907 } 908 }; 909 910 void ScShapeChilds::VisAreaChanged() const 911 { 912 ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end(); 913 ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); 914 while (aItr != aEndItr) 915 { 916 ScVisAreaChanged aVisAreaChanged(&(aItr->maViewForwarder)); 917 std::for_each(aItr->maBackShapes.begin(), aItr->maBackShapes.end(), aVisAreaChanged); 918 std::for_each(aItr->maControls.begin(), aItr->maControls.end(), aVisAreaChanged); 919 std::for_each(aItr->maForeShapes.begin(), aItr->maForeShapes.end(), aVisAreaChanged); 920 ++aItr; 921 } 922 } 923 924 ///===== IAccessibleParent ============================================== 925 926 sal_Bool ScShapeChilds::ReplaceChild (::accessibility::AccessibleShape* /* pCurrentChild */, 927 const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& /* _rxShape */, 928 const long /* _nIndex */, const ::accessibility::AccessibleShapeTreeInfo& /* _rShapeTreeInfo */) 929 throw (uno::RuntimeException) 930 { 931 DBG_ERRORFILE("should not be called in the page preview"); 932 return sal_False; 933 } 934 935 ///===== Internal ======================================================== 936 937 void ScShapeChilds::Init() 938 { 939 if(mpViewShell) 940 { 941 const ScPreviewLocationData& rData = mpViewShell->GetLocationData(); 942 MapMode aMapMode; 943 Rectangle aPixelPaintRect; 944 sal_uInt8 nRangeId; 945 sal_uInt16 nCount(rData.GetDrawRanges()); 946 for (sal_uInt16 i = 0; i < nCount; ++i) 947 { 948 rData.GetDrawRange(i, aPixelPaintRect, aMapMode, nRangeId); 949 FillShapes(aPixelPaintRect, aMapMode, nRangeId); 950 } 951 } 952 } 953 954 sal_Int32 ScShapeChilds::GetBackShapeCount() const 955 { 956 sal_Int32 nCount(0); 957 ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end(); 958 for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr ) 959 nCount += aItr->maBackShapes.size(); 960 return nCount; 961 } 962 963 uno::Reference<XAccessible> ScShapeChilds::GetBackShape(sal_Int32 nIndex) const 964 { 965 uno::Reference<XAccessible> xAccessible; 966 ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end(); 967 ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); 968 while ((aItr != aEndItr) && !xAccessible.is()) 969 { 970 sal_Int32 nCount(aItr->maBackShapes.size()); 971 if(nIndex < nCount) 972 xAccessible = GetAccShape(aItr->maBackShapes, nIndex); 973 else 974 ++aItr; 975 nIndex -= nCount; 976 } 977 978 if (nIndex >= 0) 979 throw lang::IndexOutOfBoundsException(); 980 981 return xAccessible; 982 } 983 984 sal_Int32 ScShapeChilds::GetForeShapeCount() const 985 { 986 sal_Int32 nCount(0); 987 ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end(); 988 for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr ) 989 nCount += aItr->maForeShapes.size(); 990 return nCount; 991 } 992 993 uno::Reference<XAccessible> ScShapeChilds::GetForeShape(sal_Int32 nIndex) const 994 { 995 uno::Reference<XAccessible> xAccessible; 996 ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end(); 997 ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); 998 while ((aItr != aEndItr) && !xAccessible.is()) 999 { 1000 sal_Int32 nCount(aItr->maForeShapes.size()); 1001 if(nIndex < nCount) 1002 xAccessible = GetAccShape(aItr->maForeShapes, nIndex); 1003 else 1004 ++aItr; 1005 nIndex -= nCount; 1006 } 1007 1008 if (nIndex >= 0) 1009 throw lang::IndexOutOfBoundsException(); 1010 1011 return xAccessible; 1012 } 1013 1014 sal_Int32 ScShapeChilds::GetControlCount() const 1015 { 1016 sal_Int32 nCount(0); 1017 ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end(); 1018 for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr ) 1019 nCount += aItr->maControls.size(); 1020 return nCount; 1021 } 1022 1023 uno::Reference<XAccessible> ScShapeChilds::GetControl(sal_Int32 nIndex) const 1024 { 1025 uno::Reference<XAccessible> xAccessible; 1026 ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end(); 1027 ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); 1028 while ((aItr != aEndItr) && !xAccessible.is()) 1029 { 1030 sal_Int32 nCount(aItr->maControls.size()); 1031 if(nIndex < nCount) 1032 xAccessible = GetAccShape(aItr->maControls, nIndex); 1033 else 1034 ++aItr; 1035 nIndex -= nCount; 1036 } 1037 1038 if (nIndex >= 0) 1039 throw lang::IndexOutOfBoundsException(); 1040 1041 return xAccessible; 1042 } 1043 1044 struct ScShapePointFound 1045 { 1046 Point maPoint; 1047 ScShapePointFound(const awt::Point& rPoint) : maPoint(VCLPoint(rPoint)) {} 1048 sal_Bool operator() (const ScShapeChild& rShape) 1049 { 1050 sal_Bool bResult(sal_False); 1051 if ((VCLRectangle(rShape.mpAccShape->getBounds())).IsInside(maPoint)) 1052 bResult = sal_True; 1053 return bResult; 1054 } 1055 }; 1056 1057 uno::Reference<XAccessible> ScShapeChilds::GetForegroundShapeAt(const awt::Point& rPoint) const //inclusive Controls 1058 { 1059 uno::Reference<XAccessible> xAcc; 1060 1061 ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); 1062 ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end(); 1063 while((aItr != aEndItr) && !xAcc.is()) 1064 { 1065 ScShapeChildVec::const_iterator aFindItr = std::find_if(aItr->maForeShapes.begin(), aItr->maForeShapes.end(), ScShapePointFound(rPoint)); 1066 if (aFindItr != aItr->maForeShapes.end()) 1067 xAcc = GetAccShape(*aFindItr); 1068 else 1069 { 1070 ScShapeChildVec::const_iterator aCtrlItr = std::find_if(aItr->maControls.begin(), aItr->maControls.end(), ScShapePointFound(rPoint)); 1071 if (aCtrlItr != aItr->maControls.end()) 1072 xAcc = GetAccShape(*aCtrlItr); 1073 else 1074 ++aItr; 1075 } 1076 } 1077 1078 return xAcc; 1079 } 1080 1081 uno::Reference<XAccessible> ScShapeChilds::GetBackgroundShapeAt(const awt::Point& rPoint) const 1082 { 1083 uno::Reference<XAccessible> xAcc; 1084 1085 ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); 1086 ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end(); 1087 while((aItr != aEndItr) && !xAcc.is()) 1088 { 1089 ScShapeChildVec::const_iterator aFindItr = std::find_if(aItr->maBackShapes.begin(), aItr->maBackShapes.end(), ScShapePointFound(rPoint)); 1090 if (aFindItr != aItr->maBackShapes.end()) 1091 xAcc = GetAccShape(*aFindItr); 1092 else 1093 ++aItr; 1094 } 1095 1096 return xAcc; 1097 } 1098 1099 ::accessibility::AccessibleShape* ScShapeChilds::GetAccShape(const ScShapeChild& rShape) const 1100 { 1101 if (!rShape.mpAccShape) 1102 { 1103 ::accessibility::ShapeTypeHandler& rShapeHandler = ::accessibility::ShapeTypeHandler::Instance(); 1104 ::accessibility::AccessibleShapeInfo aShapeInfo(rShape.mxShape, mpAccDoc, const_cast<ScShapeChilds*>(this)); 1105 1106 if (mpViewShell) 1107 { 1108 ::accessibility::AccessibleShapeTreeInfo aShapeTreeInfo; 1109 aShapeTreeInfo.SetSdrView(mpViewShell->GetPreview()->GetDrawView()); 1110 aShapeTreeInfo.SetController(NULL); 1111 aShapeTreeInfo.SetWindow(mpViewShell->GetWindow()); 1112 aShapeTreeInfo.SetViewForwarder(&(maShapeRanges[rShape.mnRangeId].maViewForwarder)); 1113 rShape.mpAccShape = rShapeHandler.CreateAccessibleObject(aShapeInfo, aShapeTreeInfo); 1114 if (rShape.mpAccShape) 1115 { 1116 rShape.mpAccShape->acquire(); 1117 rShape.mpAccShape->Init(); 1118 } 1119 } 1120 } 1121 return rShape.mpAccShape; 1122 } 1123 1124 ::accessibility::AccessibleShape* ScShapeChilds::GetAccShape(const ScShapeChildVec& rShapes, sal_Int32 nIndex) const 1125 { 1126 return (GetAccShape(rShapes[nIndex])); 1127 } 1128 1129 void ScShapeChilds::FillShapes(const Rectangle& aPixelPaintRect, const MapMode& aMapMode, sal_uInt8 nRangeId) 1130 { 1131 DBG_ASSERT(nRangeId < maShapeRanges.size(), "this is not a valid range for draw objects"); 1132 SdrPage* pPage = GetDrawPage(); 1133 Window* pWin = mpViewShell->GetWindow(); 1134 if (pPage && pWin) 1135 { 1136 sal_Bool bForeAdded(sal_False); 1137 sal_Bool bBackAdded(sal_False); 1138 sal_Bool bControlAdded(sal_False); 1139 Rectangle aClippedPixelPaintRect(aPixelPaintRect); 1140 if (mpAccDoc) 1141 { 1142 Rectangle aRect2(Point(0,0), mpAccDoc->GetBoundingBoxOnScreen().GetSize()); 1143 aClippedPixelPaintRect = aPixelPaintRect.GetIntersection(aRect2); 1144 } 1145 maShapeRanges[nRangeId].maPixelRect = aClippedPixelPaintRect; 1146 maShapeRanges[nRangeId].maMapMode = aMapMode; 1147 ScIAccessibleViewForwarder aViewForwarder(mpViewShell, mpAccDoc, aMapMode); 1148 maShapeRanges[nRangeId].maViewForwarder = aViewForwarder; 1149 sal_uInt32 nCount(pPage->GetObjCount()); 1150 for (sal_uInt32 i = 0; i < nCount; ++i) 1151 { 1152 SdrObject* pObj = pPage->GetObj(i); 1153 if (pObj) 1154 { 1155 uno::Reference< drawing::XShape > xShape(pObj->getUnoShape(), uno::UNO_QUERY); 1156 if (xShape.is()) 1157 { 1158 Rectangle aRect(pWin->LogicToPixel(VCLPoint(xShape->getPosition()), aMapMode), pWin->LogicToPixel(VCLSize(xShape->getSize()), aMapMode)); 1159 if(!aClippedPixelPaintRect.GetIntersection(aRect).IsEmpty()) 1160 { 1161 ScShapeChild aShape; 1162 aShape.mxShape = xShape; 1163 aShape.mnRangeId = nRangeId; 1164 switch (pObj->GetLayer()) 1165 { 1166 case SC_LAYER_INTERN: 1167 case SC_LAYER_FRONT: 1168 { 1169 maShapeRanges[nRangeId].maForeShapes.push_back(aShape); 1170 bForeAdded = sal_True; 1171 } 1172 break; 1173 case SC_LAYER_BACK: 1174 { 1175 maShapeRanges[nRangeId].maBackShapes.push_back(aShape); 1176 bBackAdded = sal_True; 1177 } 1178 break; 1179 case SC_LAYER_CONTROLS: 1180 { 1181 maShapeRanges[nRangeId].maControls.push_back(aShape); 1182 bControlAdded = sal_True; 1183 } 1184 break; 1185 default: 1186 { 1187 DBG_ERRORFILE("I don't know this layer."); 1188 } 1189 break; 1190 } 1191 } 1192 } 1193 } 1194 } 1195 if (bForeAdded) 1196 std::sort(maShapeRanges[nRangeId].maForeShapes.begin(), maShapeRanges[nRangeId].maForeShapes.end(),ScShapeChildLess()); 1197 if (bBackAdded) 1198 std::sort(maShapeRanges[nRangeId].maBackShapes.begin(), maShapeRanges[nRangeId].maBackShapes.end(),ScShapeChildLess()); 1199 if (bControlAdded) 1200 std::sort(maShapeRanges[nRangeId].maControls.begin(), maShapeRanges[nRangeId].maControls.end(),ScShapeChildLess()); 1201 } 1202 } 1203 1204 //UNUSED2008-05 sal_Bool ScShapeChilds::FindShape(ScShapeChildVec& rShapes, const uno::Reference <drawing::XShape>& xShape, ScShapeChildVec::iterator& rItr) const 1205 //UNUSED2008-05 { 1206 //UNUSED2008-05 sal_Bool bResult(sal_False); 1207 //UNUSED2008-05 ScShapeChild aShape; 1208 //UNUSED2008-05 aShape.mxShape = xShape; 1209 //UNUSED2008-05 rItr = std::lower_bound(rShapes.begin(), rShapes.end(), aShape, ScShapeChildLess()); 1210 //UNUSED2008-05 if (rItr->mxShape.get() == xShape.get()) 1211 //UNUSED2008-05 bResult = sal_True; // if the shape is found 1212 //UNUSED2008-05 1213 //UNUSED2008-05 /*#ifdef DBG_UTIL // test whether it finds truly the correct shape (perhaps it is not really sorted) 1214 //UNUSED2008-05 ScShapeChildVec::iterator aDebugItr = std::find(rShapes.begin(), rShapes.end(), aShape); 1215 //UNUSED2008-05 DBG_ASSERT(rItr == aDebugItr, "wrong Shape found"); 1216 //UNUSED2008-05 #endif*/ 1217 //UNUSED2008-05 return bResult; 1218 //UNUSED2008-05 } 1219 1220 /*void ScShapeChilds::AddShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID) 1221 { 1222 uno::Reference < XAccessible > xNew; 1223 Window* pWin = mpViewShell->GetWindow(); 1224 if (pWin) 1225 { 1226 ScShapeRangeVec::iterator aEndItr = maShapeRanges.end(); 1227 ScShapeRangeVec::iterator aItr = maShapeRanges.begin(); 1228 sal_Bool bNotify(sal_False); 1229 uno::Reference <XAccessible> xAcc; 1230 while (aItr != aEndItr) 1231 { 1232 Rectangle aLogicPaintRect(pWin->PixelToLogic(aItr->maPixelRect, aItr->maMapMode)); 1233 Rectangle aRect(VCLPoint(xShape->getPosition()), VCLSize(xShape->getSize())); 1234 if(!aRect.GetIntersection(aLogicPaintRect).IsEmpty()) 1235 { 1236 ScShapeChild aShape; 1237 aShape.mxShape = xShape; 1238 switch (aLayerID) 1239 { 1240 case SC_LAYER_INTERN: 1241 case SC_LAYER_FRONT: 1242 { 1243 SetAnchor(aShape); 1244 aItr->maForeShapes.push_back(aShape); 1245 std::sort(aItr->maForeShapes.begin(), aItr->maForeShapes.end(),ScShapeChildLess()); 1246 1247 } 1248 break; 1249 case SC_LAYER_BACK: 1250 { 1251 aItr->maBackShapes.push_back(aShape); 1252 std::sort(aItr->maBackShapes.begin(), aItr->maBackShapes.end(),ScShapeChildLess()); 1253 } 1254 break; 1255 case SC_LAYER_CONTROLS: 1256 { 1257 SetAnchor(aShape); 1258 aItr->maControls.push_back(aShape); 1259 std::sort(aItr->maControls.begin(), aItr->maControls.end(),ScShapeChildLess()); 1260 } 1261 break; 1262 default: 1263 { 1264 DBG_ERRORFILE("I don't know this layer."); 1265 } 1266 break; 1267 } 1268 if (bNotify) 1269 { 1270 xAcc = GetAccShape(aShape); 1271 AccessibleEventObject aEvent; 1272 aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc); 1273 aEvent.EventId = AccessibleEventId::CHILD; 1274 aEvent.NewValue <<= xAcc; 1275 mpAccDoc->CommitChange(aEvent); 1276 bNotify = sal_False; 1277 } 1278 xAcc = NULL; 1279 } 1280 ++aItr; 1281 } 1282 } 1283 }*/ 1284 1285 /*sal_Bool HaveToNotify(uno::Reference<XAccessible>& xAcc, ScShapeChildVec::iterator aItr) 1286 { 1287 sal_Bool bResult(sal_False); 1288 if (aItr->mpAccShape) 1289 { 1290 bResult = sal_True; 1291 xAcc = aItr->mpAccShape; 1292 } 1293 else 1294 DBG_ERRORFILE("No Accessible object found. Don't know how to notify."); 1295 return bResult; 1296 }*/ 1297 1298 /*void ScShapeChilds::RemoveShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID) 1299 { 1300 ScShapeRangeVec::iterator aEndItr = maShapeRanges.end(); 1301 ScShapeRangeVec::iterator aItr = maShapeRanges.begin(); 1302 ScShapeChildVec::iterator aEraseItr; 1303 sal_Bool bNotify(sal_False); 1304 uno::Reference <XAccessible> xAcc; 1305 while (aItr != aEndItr) 1306 { 1307 switch (aLayerID) 1308 { 1309 case SC_LAYER_INTERN: 1310 case SC_LAYER_FRONT: 1311 { 1312 if (FindShape(aItr->maForeShapes, xShape, aEraseItr)) 1313 { 1314 bNotify = HaveToNotify(xAcc, aEraseItr); 1315 aItr->maForeShapes.erase(aEraseItr); 1316 } 1317 } 1318 break; 1319 case SC_LAYER_BACK: 1320 { 1321 if (FindShape(aItr->maBackShapes, xShape, aEraseItr)) 1322 { 1323 bNotify = HaveToNotify(xAcc, aEraseItr); 1324 aItr->maBackShapes.erase(aEraseItr); 1325 } 1326 } 1327 break; 1328 case SC_LAYER_CONTROLS: 1329 { 1330 if (FindShape(aItr->maControls, xShape, aEraseItr)) 1331 { 1332 bNotify = HaveToNotify(xAcc, aEraseItr); 1333 aItr->maControls.erase(aEraseItr); 1334 } 1335 } 1336 break; 1337 default: 1338 { 1339 DBG_ERRORFILE("I don't know this layer."); 1340 } 1341 break; 1342 } 1343 if (bNotify) 1344 { 1345 AccessibleEventObject aEvent; 1346 aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc); 1347 aEvent.EventId = AccessibleEventId::CHILD; 1348 aEvent.OldValue <<= xAcc; 1349 mpAccDoc->CommitChange(aEvent); 1350 bNotify = sal_False; 1351 } 1352 xAcc = NULL; 1353 ++aItr; 1354 } 1355 }*/ 1356 1357 SdrPage* ScShapeChilds::GetDrawPage() const 1358 { 1359 SCTAB nTab( mpViewShell->GetLocationData().GetPrintTab() ); 1360 SdrPage* pDrawPage = NULL; 1361 if (mpViewShell) 1362 { 1363 ScDocument* pDoc = mpViewShell->GetDocument(); 1364 if (pDoc && pDoc->GetDrawLayer()) 1365 { 1366 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); 1367 if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab)) 1368 pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab))); 1369 } 1370 } 1371 return pDrawPage; 1372 } 1373 1374 struct ScPagePreviewCountData 1375 { 1376 // order is background shapes, header, table or notes, footer, foreground shapes, controls 1377 1378 Rectangle aVisRect; 1379 long nBackShapes; 1380 long nHeaders; 1381 long nTables; 1382 long nNoteParagraphs; 1383 long nFooters; 1384 long nForeShapes; 1385 long nControls; 1386 1387 ScPagePreviewCountData( const ScPreviewLocationData& rData, Window* pSizeWindow, 1388 ScNotesChilds* pNotesChilds, ScShapeChilds* pShapeChilds ); 1389 1390 long GetTotal() const 1391 { 1392 return nBackShapes + nHeaders + nTables + nNoteParagraphs + nFooters + nForeShapes + nControls; 1393 } 1394 }; 1395 1396 ScPagePreviewCountData::ScPagePreviewCountData( const ScPreviewLocationData& rData, 1397 Window* pSizeWindow, ScNotesChilds* pNotesChilds, 1398 ScShapeChilds* pShapeChilds) : 1399 nBackShapes( 0 ), 1400 nHeaders( 0 ), 1401 nTables( 0 ), 1402 nNoteParagraphs( 0 ), 1403 nFooters( 0 ), 1404 nForeShapes( 0 ), 1405 nControls( 0 ) 1406 { 1407 Size aOutputSize; 1408 if ( pSizeWindow ) 1409 aOutputSize = pSizeWindow->GetOutputSizePixel(); 1410 Point aPoint; 1411 aVisRect = Rectangle( aPoint, aOutputSize ); 1412 1413 Rectangle aObjRect; 1414 1415 if ( rData.GetHeaderPosition( aObjRect ) && aObjRect.IsOver( aVisRect ) ) 1416 nHeaders = 1; 1417 1418 if ( rData.GetFooterPosition( aObjRect ) && aObjRect.IsOver( aVisRect ) ) 1419 nFooters = 1; 1420 1421 if ( rData.HasCellsInRange( aVisRect ) ) 1422 nTables = 1; 1423 1424 //! shapes... 1425 nBackShapes = pShapeChilds->GetBackShapeCount(); 1426 nForeShapes = pShapeChilds->GetForeShapeCount(); 1427 nControls = pShapeChilds->GetControlCount(); 1428 1429 // there are only notes if there is no table 1430 if (nTables == 0) 1431 nNoteParagraphs = pNotesChilds->GetChildsCount(); 1432 } 1433 1434 //===== internal ======================================================== 1435 1436 ScAccessibleDocumentPagePreview::ScAccessibleDocumentPagePreview( 1437 const uno::Reference<XAccessible>& rxParent, ScPreviewShell* pViewShell ) : 1438 ScAccessibleDocumentBase(rxParent), 1439 mpViewShell(pViewShell), 1440 mpNotesChilds(NULL), 1441 mpShapeChilds(NULL), 1442 mpTable(NULL), 1443 mpHeader(NULL), 1444 mpFooter(NULL) 1445 { 1446 if (pViewShell) 1447 pViewShell->AddAccessibilityObject(*this); 1448 1449 // GetNotesChilds(); not neccessary and reduces the creation performance 1450 // GetShapeChilds(); 1451 } 1452 1453 ScAccessibleDocumentPagePreview::~ScAccessibleDocumentPagePreview(void) 1454 { 1455 if (!ScAccessibleDocumentBase::IsDefunc() && !rBHelper.bInDispose) 1456 { 1457 // increment refcount to prevent double call off dtor 1458 osl_incrementInterlockedCount( &m_refCount ); 1459 // call dispose to inform object wich have a weak reference to this object 1460 dispose(); 1461 } 1462 } 1463 1464 void SAL_CALL ScAccessibleDocumentPagePreview::disposing() 1465 { 1466 ScUnoGuard aGuard; 1467 if (mpTable) 1468 { 1469 mpTable->release(); 1470 mpTable = NULL; 1471 } 1472 if (mpHeader) 1473 { 1474 mpHeader->release(); 1475 mpHeader = NULL; 1476 } 1477 if (mpFooter) 1478 { 1479 mpFooter->release(); 1480 mpFooter = NULL; 1481 } 1482 1483 if (mpViewShell) 1484 { 1485 mpViewShell->RemoveAccessibilityObject(*this); 1486 mpViewShell = NULL; 1487 } 1488 1489 // #100593# no need to Dispose the AccessibleTextHelper, 1490 // as long as mpNotesChilds are destructed here 1491 if (mpNotesChilds) 1492 DELETEZ(mpNotesChilds); 1493 1494 if (mpShapeChilds) 1495 DELETEZ(mpShapeChilds); 1496 1497 ScAccessibleDocumentBase::disposing(); 1498 } 1499 1500 //===== SfxListener ===================================================== 1501 1502 void ScAccessibleDocumentPagePreview::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) 1503 { 1504 if (rHint.ISA( SfxSimpleHint ) ) 1505 { 1506 const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint; 1507 // only notify if child exist, otherwise it is not necessary 1508 if ((rRef.GetId() == SC_HINT_DATACHANGED)) 1509 { 1510 if (mpTable) // if there is no table there is nothing to notify, because no one recongnizes the change 1511 { 1512 { 1513 uno::Reference<XAccessible> xAcc = mpTable; 1514 AccessibleEventObject aEvent; 1515 aEvent.EventId = AccessibleEventId::CHILD; 1516 aEvent.Source = uno::Reference< XAccessibleContext >(this); 1517 aEvent.OldValue <<= xAcc; 1518 CommitChange(aEvent); 1519 } 1520 1521 mpTable->dispose(); 1522 mpTable->release(); 1523 mpTable = NULL; 1524 } 1525 1526 Size aOutputSize; 1527 Window* pSizeWindow = mpViewShell->GetWindow(); 1528 if ( pSizeWindow ) 1529 aOutputSize = pSizeWindow->GetOutputSizePixel(); 1530 Point aPoint; 1531 Rectangle aVisRect( aPoint, aOutputSize ); 1532 GetNotesChilds()->DataChanged(aVisRect); 1533 1534 GetShapeChilds()->DataChanged(); 1535 1536 const ScPreviewLocationData& rData = mpViewShell->GetLocationData(); 1537 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() ); 1538 1539 if (aCount.nTables > 0) 1540 { 1541 //! order is background shapes, header, table or notes, footer, foreground shapes, controls 1542 sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders); 1543 1544 mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex ); 1545 mpTable->acquire(); 1546 mpTable->Init(); 1547 1548 { 1549 uno::Reference<XAccessible> xAcc = mpTable; 1550 AccessibleEventObject aEvent; 1551 aEvent.EventId = AccessibleEventId::CHILD; 1552 aEvent.Source = uno::Reference< XAccessibleContext >(this); 1553 aEvent.NewValue <<= xAcc; 1554 CommitChange(aEvent); 1555 } 1556 } 1557 } 1558 else if (rRef.GetId() == SC_HINT_ACC_MAKEDRAWLAYER) 1559 { 1560 GetShapeChilds()->SetDrawBroadcaster(); 1561 } 1562 else if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED) 1563 { 1564 Size aOutputSize; 1565 Window* pSizeWindow = mpViewShell->GetWindow(); 1566 if ( pSizeWindow ) 1567 aOutputSize = pSizeWindow->GetOutputSizePixel(); 1568 Point aPoint; 1569 Rectangle aVisRect( aPoint, aOutputSize ); 1570 GetNotesChilds()->DataChanged(aVisRect); 1571 1572 GetShapeChilds()->VisAreaChanged(); 1573 1574 AccessibleEventObject aEvent; 1575 aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED; 1576 aEvent.Source = uno::Reference< XAccessibleContext >(this); 1577 CommitChange(aEvent); 1578 } 1579 } 1580 else if ( rHint.ISA(ScAccWinFocusLostHint) ) 1581 { 1582 CommitFocusLost(); 1583 } 1584 else if ( rHint.ISA(ScAccWinFocusGotHint) ) 1585 { 1586 CommitFocusGained(); 1587 } 1588 ScAccessibleDocumentBase::Notify(rBC, rHint); 1589 } 1590 1591 //===== XAccessibleComponent ============================================ 1592 1593 uno::Reference< XAccessible > SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleAtPoint( const awt::Point& rPoint ) 1594 throw (uno::RuntimeException) 1595 { 1596 uno::Reference<XAccessible> xAccessible; 1597 if (containsPoint(rPoint)) 1598 { 1599 ScUnoGuard aGuard; 1600 IsObjectValid(); 1601 1602 if ( mpViewShell ) 1603 { 1604 xAccessible = GetShapeChilds()->GetForegroundShapeAt(rPoint); 1605 if (!xAccessible.is()) 1606 { 1607 const ScPreviewLocationData& rData = mpViewShell->GetLocationData(); 1608 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() ); 1609 1610 /* if ( rData.HasCellsInRange( Rectangle( rPoint, rPoint ) ) ) 1611 { 1612 if ( !mpTable && (aCount.nTables > 0) ) 1613 { 1614 //! order is background shapes, header, table or notes, footer, foreground shapes, controls 1615 sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders); 1616 1617 mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex ); 1618 mpTable->acquire(); 1619 mpTable->Init(); 1620 } 1621 xAccessible = mpTable; 1622 }*/ 1623 if ( !mpTable && (aCount.nTables > 0) ) 1624 { 1625 //! order is background shapes, header, table or notes, footer, foreground shapes, controls 1626 sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders); 1627 1628 mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex ); 1629 mpTable->acquire(); 1630 mpTable->Init(); 1631 } 1632 if (mpTable && VCLRectangle(mpTable->getBounds()).IsInside(VCLPoint(rPoint))) 1633 xAccessible = mpTable; 1634 } 1635 if (!xAccessible.is()) 1636 xAccessible = GetNotesChilds()->GetAt(rPoint); 1637 if (!xAccessible.is()) 1638 { 1639 if (!mpHeader || !mpFooter) 1640 { 1641 const ScPreviewLocationData& rData = mpViewShell->GetLocationData(); 1642 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() ); 1643 1644 if (!mpHeader) 1645 { 1646 mpHeader = new ScAccessiblePageHeader( this, mpViewShell, sal_True, aCount.nBackShapes + aCount.nHeaders - 1); 1647 mpHeader->acquire(); 1648 } 1649 if (!mpFooter) 1650 { 1651 mpFooter = new ScAccessiblePageHeader( this, mpViewShell, sal_False, aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters - 1 ); 1652 mpFooter->acquire(); 1653 } 1654 } 1655 1656 Point aPoint(VCLPoint(rPoint)); 1657 1658 if (VCLRectangle(mpHeader->getBounds()).IsInside(aPoint)) 1659 xAccessible = mpHeader; 1660 else if (VCLRectangle(mpFooter->getBounds()).IsInside(aPoint)) 1661 xAccessible = mpFooter; 1662 } 1663 if (!xAccessible.is()) 1664 xAccessible = GetShapeChilds()->GetBackgroundShapeAt(rPoint); 1665 } 1666 } 1667 1668 return xAccessible; 1669 } 1670 1671 void SAL_CALL ScAccessibleDocumentPagePreview::grabFocus() throw (uno::RuntimeException) 1672 { 1673 ScUnoGuard aGuard; 1674 IsObjectValid(); 1675 if (getAccessibleParent().is()) 1676 { 1677 uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY); 1678 if (xAccessibleComponent.is()) 1679 { 1680 // just grab the focus for the window 1681 xAccessibleComponent->grabFocus(); 1682 } 1683 } 1684 } 1685 1686 //===== XAccessibleContext ============================================== 1687 1688 sal_Int32 SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleChildCount(void) throw (uno::RuntimeException) 1689 { 1690 ScUnoGuard aGuard; 1691 IsObjectValid(); 1692 1693 long nRet = 0; 1694 if ( mpViewShell ) 1695 { 1696 ScPagePreviewCountData aCount( mpViewShell->GetLocationData(), mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() ); 1697 nRet = aCount.GetTotal(); 1698 } 1699 1700 return nRet; 1701 } 1702 1703 uno::Reference<XAccessible> SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleChild(sal_Int32 nIndex) 1704 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 1705 { 1706 ScUnoGuard aGuard; 1707 IsObjectValid(); 1708 uno::Reference<XAccessible> xAccessible; 1709 1710 if ( mpViewShell ) 1711 { 1712 const ScPreviewLocationData& rData = mpViewShell->GetLocationData(); 1713 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() ); 1714 1715 if ( nIndex < aCount.nBackShapes ) 1716 { 1717 xAccessible = GetShapeChilds()->GetBackShape(nIndex); 1718 } 1719 else if ( nIndex < aCount.nBackShapes + aCount.nHeaders ) 1720 { 1721 if ( !mpHeader ) 1722 { 1723 mpHeader = new ScAccessiblePageHeader( this, mpViewShell, sal_True, nIndex ); 1724 mpHeader->acquire(); 1725 } 1726 1727 xAccessible = mpHeader; 1728 } 1729 else if ( nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nTables ) 1730 { 1731 if ( !mpTable ) 1732 { 1733 mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex ); 1734 mpTable->acquire(); 1735 mpTable->Init(); 1736 } 1737 xAccessible = mpTable; 1738 } 1739 else if ( nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nNoteParagraphs ) 1740 { 1741 xAccessible = GetNotesChilds()->GetChild(nIndex - aCount.nBackShapes - aCount.nHeaders); 1742 } 1743 else if ( (nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters) ) 1744 { 1745 if ( !mpFooter ) 1746 { 1747 mpFooter = new ScAccessiblePageHeader( this, mpViewShell, sal_False, nIndex ); 1748 mpFooter->acquire(); 1749 } 1750 xAccessible = mpFooter; 1751 } 1752 else 1753 { 1754 sal_Int32 nIdx(nIndex - (aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters)); 1755 if (nIdx < aCount.nForeShapes) 1756 xAccessible = GetShapeChilds()->GetForeShape(nIdx); 1757 else 1758 xAccessible = GetShapeChilds()->GetControl(nIdx - aCount.nForeShapes); 1759 } 1760 } 1761 1762 if ( !xAccessible.is() ) 1763 throw lang::IndexOutOfBoundsException(); 1764 1765 return xAccessible; 1766 } 1767 1768 /// Return the set of current states. 1769 uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleStateSet(void) 1770 throw (uno::RuntimeException) 1771 { 1772 ScUnoGuard aGuard; 1773 uno::Reference<XAccessibleStateSet> xParentStates; 1774 if (getAccessibleParent().is()) 1775 { 1776 uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext(); 1777 xParentStates = xParentContext->getAccessibleStateSet(); 1778 } 1779 utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper(); 1780 if (IsDefunc(xParentStates)) 1781 pStateSet->AddState(AccessibleStateType::DEFUNC); 1782 else 1783 { 1784 // never editable 1785 pStateSet->AddState(AccessibleStateType::ENABLED); 1786 pStateSet->AddState(AccessibleStateType::OPAQUE); 1787 if (isShowing()) 1788 pStateSet->AddState(AccessibleStateType::SHOWING); 1789 if (isVisible()) 1790 pStateSet->AddState(AccessibleStateType::VISIBLE); 1791 } 1792 return pStateSet; 1793 } 1794 1795 //===== XServiceInfo ==================================================== 1796 1797 ::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::getImplementationName(void) 1798 throw (uno::RuntimeException) 1799 { 1800 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessibleDocumentPagePreview")); 1801 } 1802 1803 uno::Sequence< ::rtl::OUString> SAL_CALL ScAccessibleDocumentPagePreview::getSupportedServiceNames(void) 1804 throw (uno::RuntimeException) 1805 { 1806 uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames(); 1807 sal_Int32 nOldSize(aSequence.getLength()); 1808 aSequence.realloc(nOldSize + 1); 1809 ::rtl::OUString* pNames = aSequence.getArray(); 1810 1811 pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheetPageView")); 1812 1813 return aSequence; 1814 } 1815 1816 //===== XTypeProvider ======================================================= 1817 1818 uno::Sequence<sal_Int8> SAL_CALL 1819 ScAccessibleDocumentPagePreview::getImplementationId(void) 1820 throw (uno::RuntimeException) 1821 { 1822 ScUnoGuard aGuard; 1823 IsObjectValid(); 1824 static uno::Sequence<sal_Int8> aId; 1825 if (aId.getLength() == 0) 1826 { 1827 aId.realloc (16); 1828 rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True); 1829 } 1830 return aId; 1831 } 1832 1833 //===== internal ======================================================== 1834 1835 ::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::createAccessibleDescription(void) 1836 throw (uno::RuntimeException) 1837 { 1838 rtl::OUString sDescription = String(ScResId(STR_ACC_PREVIEWDOC_DESCR)); 1839 return sDescription; 1840 } 1841 1842 ::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::createAccessibleName(void) 1843 throw (uno::RuntimeException) 1844 { 1845 rtl::OUString sName = String(ScResId(STR_ACC_PREVIEWDOC_NAME)); 1846 return sName; 1847 } 1848 1849 Rectangle ScAccessibleDocumentPagePreview::GetBoundingBoxOnScreen() const throw (uno::RuntimeException) 1850 { 1851 Rectangle aRect; 1852 if (mpViewShell) 1853 { 1854 Window* pWindow = mpViewShell->GetWindow(); 1855 if (pWindow) 1856 aRect = pWindow->GetWindowExtentsRelative(NULL); 1857 } 1858 return aRect; 1859 } 1860 1861 Rectangle ScAccessibleDocumentPagePreview::GetBoundingBox() const throw (uno::RuntimeException) 1862 { 1863 Rectangle aRect; 1864 if (mpViewShell) 1865 { 1866 Window* pWindow = mpViewShell->GetWindow(); 1867 if (pWindow) 1868 aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow()); 1869 } 1870 return aRect; 1871 } 1872 1873 sal_Bool ScAccessibleDocumentPagePreview::IsDefunc( 1874 const uno::Reference<XAccessibleStateSet>& rxParentStates) 1875 { 1876 return ScAccessibleContextBase::IsDefunc() || !getAccessibleParent().is() || 1877 (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC)); 1878 } 1879 1880 ScNotesChilds* ScAccessibleDocumentPagePreview::GetNotesChilds() 1881 { 1882 if (!mpNotesChilds && mpViewShell) 1883 { 1884 mpNotesChilds = new ScNotesChilds(mpViewShell, this); 1885 1886 const ScPreviewLocationData& rData = mpViewShell->GetLocationData(); 1887 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() ); 1888 1889 //! order is background shapes, header, table or notes, footer, foreground shapes, controls 1890 mpNotesChilds->Init(aCount.aVisRect, aCount.nBackShapes + aCount.nHeaders); 1891 } 1892 return mpNotesChilds; 1893 } 1894 1895 ScShapeChilds* ScAccessibleDocumentPagePreview::GetShapeChilds() 1896 { 1897 if (!mpShapeChilds && mpViewShell) 1898 { 1899 mpShapeChilds = new ScShapeChilds(mpViewShell, this); 1900 mpShapeChilds->Init(); 1901 } 1902 1903 return mpShapeChilds; 1904 } 1905 1906 //UNUSED2009-05 uno::Reference < XAccessible > ScAccessibleDocumentPagePreview::GetCurrentAccessibleTable() 1907 //UNUSED2009-05 { 1908 //UNUSED2009-05 if (!mpTable) 1909 //UNUSED2009-05 { 1910 //UNUSED2009-05 if ( mpViewShell ) 1911 //UNUSED2009-05 { 1912 //UNUSED2009-05 const ScPreviewLocationData& rData = mpViewShell->GetLocationData(); 1913 //UNUSED2009-05 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() ); 1914 //UNUSED2009-05 //! order is background shapes, header, table or notes, footer, foreground shapes, controls 1915 //UNUSED2009-05 sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders); 1916 //UNUSED2009-05 1917 //UNUSED2009-05 mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex ); 1918 //UNUSED2009-05 mpTable->acquire(); 1919 //UNUSED2009-05 mpTable->Init(); 1920 //UNUSED2009-05 } 1921 //UNUSED2009-05 } 1922 //UNUSED2009-05 return mpTable; 1923 //UNUSED2009-05 } 1924 1925 //UNUSED2009-05 void ScAccessibleDocumentPagePreview::ChildCountChanged() 1926 //UNUSED2009-05 { 1927 //UNUSED2009-05 if (mpViewShell) 1928 //UNUSED2009-05 { 1929 //UNUSED2009-05 const ScPreviewLocationData& rData = mpViewShell->GetLocationData(); 1930 //UNUSED2009-05 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() ); 1931 //UNUSED2009-05 //! order is background shapes, header, table or notes, footer, foreground shapes, controls 1932 //UNUSED2009-05 if(mpHeader) 1933 //UNUSED2009-05 mpHeader->SetCurrentIndexInParent(aCount.nBackShapes); 1934 //UNUSED2009-05 if (mpTable) 1935 //UNUSED2009-05 mpTable->SetCurrentIndexInParent(aCount.nBackShapes + aCount.nHeaders); 1936 //UNUSED2009-05 if (mpFooter) 1937 //UNUSED2009-05 mpFooter->SetCurrentIndexInParent(aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs); 1938 //UNUSED2009-05 1939 //UNUSED2009-05 if (mpNotesChilds) 1940 //UNUSED2009-05 mpNotesChilds->SetOffset(aCount.nBackShapes + aCount.nHeaders); 1941 //UNUSED2009-05 } 1942 //UNUSED2009-05 } 1943