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 // ============================================================================ 32 #include "AccessibleCsvControl.hxx" 33 #include <com/sun/star/accessibility/AccessibleRole.hpp> 34 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLERELATIONTYPE_HPP_ 35 #include <com/sun/star/accessibility/AccessibleRelationType.hpp> 36 #endif 37 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_ 38 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 39 #endif 40 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 41 #include <com/sun/star/accessibility/AccessibleTextType.hpp> 42 #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp> 43 #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp> 44 #include <tools/debug.hxx> 45 #include <rtl/uuid.h> 46 #include <toolkit/helper/convert.hxx> 47 #include <unotools/accessiblerelationsethelper.hxx> 48 #ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX 49 #include <unotools/accessiblestatesethelper.hxx> 50 #endif 51 #include <comphelper/sequence.hxx> 52 #include "scitems.hxx" 53 #include <editeng/fontitem.hxx> 54 #include <editeng/fhgtitem.hxx> 55 #include <editeng/langitem.hxx> 56 #include "csvcontrol.hxx" 57 #include "csvruler.hxx" 58 #include "csvgrid.hxx" 59 #include "AccessibleText.hxx" 60 #include "editsrc.hxx" 61 #include "unoguard.hxx" 62 #include "scresid.hxx" 63 #include "sc.hrc" 64 #include "scmod.hxx" 65 #include <svtools/colorcfg.hxx> 66 // ause 67 #include "editutil.hxx" 68 69 using ::rtl::OUString; 70 using ::rtl::OUStringBuffer; 71 using ::utl::AccessibleRelationSetHelper; 72 using ::utl::AccessibleStateSetHelper; 73 using ::accessibility::AccessibleStaticTextBase; 74 using ::com::sun::star::uno::Any; 75 using ::com::sun::star::uno::Reference; 76 using ::com::sun::star::uno::Sequence; 77 using ::com::sun::star::uno::RuntimeException; 78 using ::com::sun::star::uno::XInterface; 79 using ::com::sun::star::lang::DisposedException; 80 using ::com::sun::star::lang::IndexOutOfBoundsException; 81 using ::com::sun::star::lang::IllegalArgumentException; 82 using ::com::sun::star::beans::PropertyValue; 83 using namespace ::com::sun::star::accessibility; 84 85 86 // ---------------------------------------------------------------------------- 87 88 const sal_uInt16 nRulerRole = AccessibleRole::TEXT; 89 const sal_uInt16 nGridRole = AccessibleRole::TABLE; 90 const sal_uInt16 nCellRole = AccessibleRole::TEXT; 91 92 #define CREATE_OUSTRING( name ) OUString( RTL_CONSTASCII_USTRINGPARAM( name ) ) 93 94 #define RULER_IMPL_NAME "ScAccessibleCsvRuler" 95 #define GRID_IMPL_NAME "ScAccessibleCsvGrid" 96 #define CELL_IMPL_NAME "ScAccessibleCsvCell" 97 98 const sal_Unicode cRulerDot = '.'; 99 const sal_Unicode cRulerLine = '|'; 100 101 const sal_Int32 CSV_LINE_HEADER = CSV_POS_INVALID; 102 const sal_uInt32 CSV_COLUMN_HEADER = CSV_COLUMN_INVALID; 103 104 105 // CSV base control =========================================================== 106 107 DBG_NAME( ScAccessibleCsvControl ) 108 109 ScAccessibleCsvControl::ScAccessibleCsvControl( 110 const Reference< XAccessible >& rxParent, 111 ScCsvControl& rControl, 112 sal_uInt16 nRole ) : 113 ScAccessibleContextBase( rxParent, nRole ), 114 mpControl( &rControl ) 115 { 116 DBG_CTOR( ScAccessibleCsvControl, NULL ); 117 } 118 119 ScAccessibleCsvControl::~ScAccessibleCsvControl() 120 { 121 DBG_DTOR( ScAccessibleCsvControl, NULL ); 122 implDispose(); 123 } 124 125 void SAL_CALL ScAccessibleCsvControl::disposing() 126 { 127 ScUnoGuard aGuard; 128 mpControl = NULL; 129 ScAccessibleContextBase::disposing(); 130 } 131 132 133 // XAccessibleComponent ------------------------------------------------------- 134 135 Reference< XAccessible > SAL_CALL ScAccessibleCsvControl::getAccessibleAtPoint( const AwtPoint& /* rPoint */ ) 136 throw( RuntimeException ) 137 { 138 ensureAlive(); 139 return NULL; 140 } 141 142 sal_Bool SAL_CALL ScAccessibleCsvControl::isVisible() throw( RuntimeException ) 143 { 144 ScUnoGuard aGuard; 145 ensureAlive(); 146 return implGetControl().IsVisible(); 147 } 148 149 void SAL_CALL ScAccessibleCsvControl::grabFocus() throw( RuntimeException ) 150 { 151 ScUnoGuard aGuard; 152 ensureAlive(); 153 implGetControl().GrabFocus(); 154 } 155 156 157 // events --------------------------------------------------------------------- 158 159 void ScAccessibleCsvControl::SendFocusEvent( bool bFocused ) 160 { 161 if( bFocused ) 162 CommitFocusGained(); 163 else 164 CommitFocusLost(); 165 } 166 167 void ScAccessibleCsvControl::SendCaretEvent() 168 { 169 DBG_ERRORFILE( "ScAccessibleCsvControl::SendCaretEvent - Illegal call" ); 170 } 171 172 void ScAccessibleCsvControl::SendVisibleEvent() 173 { 174 AccessibleEventObject aEvent; 175 aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED; 176 aEvent.Source = Reference< XAccessible >( this ); 177 CommitChange( aEvent ); 178 } 179 180 void ScAccessibleCsvControl::SendSelectionEvent() 181 { 182 AccessibleEventObject aEvent; 183 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; 184 aEvent.Source = Reference< XAccessible >( this ); 185 CommitChange( aEvent ); 186 } 187 188 void ScAccessibleCsvControl::SendTableUpdateEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */, bool /* bAllRows */ ) 189 { 190 DBG_ERRORFILE( "ScAccessibleCsvControl::SendTableUpdateEvent - Illegal call" ); 191 } 192 193 void ScAccessibleCsvControl::SendInsertColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ ) 194 { 195 DBG_ERRORFILE( "ScAccessibleCsvControl::SendInsertColumnEvent - Illegal call" ); 196 } 197 198 void ScAccessibleCsvControl::SendRemoveColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ ) 199 { 200 DBG_ERRORFILE( "ScAccessibleCsvControl::SendRemoveColumnEvent - Illegal call" ); 201 } 202 203 204 // helpers -------------------------------------------------------------------- 205 206 Rectangle ScAccessibleCsvControl::GetBoundingBoxOnScreen() const throw( RuntimeException ) 207 { 208 ScUnoGuard aGuard; 209 ensureAlive(); 210 return implGetControl().GetWindowExtentsRelative( NULL ); 211 } 212 213 Rectangle ScAccessibleCsvControl::GetBoundingBox() const throw( RuntimeException ) 214 { 215 ScUnoGuard aGuard; 216 ensureAlive(); 217 return implGetControl().GetWindowExtentsRelative( implGetControl().GetAccessibleParentWindow() ); 218 } 219 220 void ScAccessibleCsvControl::getUuid( Sequence< sal_Int8 >& rSeq ) 221 { 222 ScUnoGuard aGuard; 223 ensureAlive(); 224 if( !rSeq.hasElements() ) 225 { 226 rSeq.realloc( 16 ); 227 rtl_createUuid( reinterpret_cast< sal_uInt8* >( rSeq.getArray() ), NULL, sal_True ); 228 } 229 } 230 231 void ScAccessibleCsvControl::ensureAlive() const throw( DisposedException ) 232 { 233 if( !implIsAlive() ) 234 throw DisposedException(); 235 } 236 237 ScCsvControl& ScAccessibleCsvControl::implGetControl() const 238 { 239 DBG_ASSERT( mpControl, "ScAccessibleCsvControl::implGetControl - missing control" ); 240 return *mpControl; 241 } 242 243 Reference< XAccessible > ScAccessibleCsvControl::implGetChildByRole( 244 const Reference< XAccessible >& rxParentObj, sal_uInt16 nRole ) throw( RuntimeException ) 245 { 246 Reference< XAccessible > xAccObj; 247 if( rxParentObj.is() ) 248 { 249 Reference< XAccessibleContext > xParentCtxt = rxParentObj->getAccessibleContext(); 250 if( xParentCtxt.is() ) 251 { 252 sal_Int32 nCount = xParentCtxt->getAccessibleChildCount(); 253 sal_Int32 nIndex = 0; 254 while( !xAccObj.is() && (nIndex < nCount) ) 255 { 256 Reference< XAccessible > xCurrObj = xParentCtxt->getAccessibleChild( nIndex ); 257 if( xCurrObj.is() ) 258 { 259 Reference< XAccessibleContext > xCurrCtxt = xCurrObj->getAccessibleContext(); 260 if( xCurrCtxt.is() && (xCurrCtxt->getAccessibleRole() == nRole) ) 261 xAccObj = xCurrObj; 262 } 263 ++nIndex; 264 } 265 } 266 } 267 return xAccObj; 268 } 269 270 AccessibleStateSetHelper* ScAccessibleCsvControl::implCreateStateSet() 271 { 272 ScUnoGuard aGuard; 273 AccessibleStateSetHelper* pStateSet = new AccessibleStateSetHelper(); 274 if( implIsAlive() ) 275 { 276 const ScCsvControl& rCtrl = implGetControl(); 277 pStateSet->AddState( AccessibleStateType::OPAQUE ); 278 if( rCtrl.IsEnabled() ) 279 pStateSet->AddState( AccessibleStateType::ENABLED ); 280 if( isShowing() ) 281 pStateSet->AddState( AccessibleStateType::SHOWING ); 282 if( isVisible() ) 283 pStateSet->AddState( AccessibleStateType::VISIBLE ); 284 } 285 else 286 pStateSet->AddState( AccessibleStateType::DEFUNC ); 287 return pStateSet; 288 } 289 290 void ScAccessibleCsvControl::implDispose() 291 { 292 if( implIsAlive() ) 293 { 294 // prevent multiple call of dtor 295 osl_incrementInterlockedCount( &m_refCount ); 296 dispose(); 297 } 298 } 299 300 Point ScAccessibleCsvControl::implGetAbsPos( const Point& rPos ) const 301 { 302 return rPos + implGetControl().GetWindowExtentsRelative( NULL ).TopLeft(); 303 } 304 305 306 // Ruler ====================================================================== 307 308 /** Converts a ruler cursor position to API text index. */ 309 sal_Int32 lcl_GetApiPos( sal_Int32 nRulerPos ) 310 { 311 sal_Int32 nApiPos = nRulerPos; 312 sal_Int32 nStart = (nRulerPos - 1) / 10; 313 sal_Int32 nExp = 1; 314 while( nStart >= nExp ) 315 { 316 nApiPos += nStart - nExp + 1; 317 nExp *= 10; 318 } 319 return ::std::max( nApiPos, static_cast<sal_Int32>(0) ); 320 } 321 322 /** Converts an API text index to a ruler cursor position. */ 323 sal_Int32 lcl_GetRulerPos( sal_Int32 nApiPos ) 324 { 325 sal_Int32 nDiv = 10; 326 sal_Int32 nExp = 10; 327 sal_Int32 nRulerPos = 0; 328 sal_Int32 nApiBase = 0; 329 sal_Int32 nApiLimit = 10; 330 while( nApiPos >= nApiLimit ) 331 { 332 ++nDiv; 333 nRulerPos = nExp; 334 nExp *= 10; 335 nApiBase = nApiLimit; 336 nApiLimit = lcl_GetApiPos( nExp ); 337 } 338 sal_Int32 nRelPos = nApiPos - nApiBase; 339 return nRulerPos + nRelPos / nDiv * 10 + ::std::max( nRelPos % nDiv - nDiv + 10L, 0L ); 340 } 341 342 /** Expands the sequence's size and returns the base index of the new inserted elements. */ 343 inline sal_Int32 lcl_ExpandSequence( Sequence< PropertyValue >& rSeq, sal_Int32 nExp ) 344 { 345 DBG_ASSERT( nExp > 0, "lcl_ExpandSequence - invalid value" ); 346 rSeq.realloc( rSeq.getLength() + nExp ); 347 return rSeq.getLength() - nExp; 348 } 349 350 /** Fills the property value rVal with the specified name and value from the item. */ 351 inline void lcl_FillProperty( PropertyValue& rVal, const OUString& rPropName, const SfxPoolItem& rItem, sal_uInt8 nMID ) 352 { 353 rVal.Name = rPropName; 354 rItem.QueryValue( rVal.Value, nMID ); 355 } 356 357 /** Fills the sequence with all font attributes of rFont. */ 358 void lcl_FillFontAttributes( Sequence< PropertyValue >& rSeq, const Font& rFont ) 359 { 360 SvxFontItem aFontItem( rFont.GetFamily(), rFont.GetName(), rFont.GetStyleName(), rFont.GetPitch(), rFont.GetCharSet(), ATTR_FONT ); 361 SvxFontHeightItem aHeightItem( rFont.GetSize().Height(), 100, ATTR_FONT_HEIGHT ); 362 SvxLanguageItem aLangItem( rFont.GetLanguage(), ATTR_FONT_LANGUAGE ); 363 364 sal_Int32 nIndex = lcl_ExpandSequence( rSeq, 7 ); 365 lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontName" ), aFontItem, MID_FONT_FAMILY_NAME ); 366 lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontFamily" ), aFontItem, MID_FONT_FAMILY ); 367 lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontStyleName" ), aFontItem, MID_FONT_STYLE_NAME ); 368 lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontCharSet" ), aFontItem, MID_FONT_PITCH ); 369 lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontPitch" ), aFontItem, MID_FONT_CHAR_SET ); 370 lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharHeight" ), aHeightItem, MID_FONTHEIGHT ); 371 lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharLocale" ), aLangItem, MID_LANG_LOCALE ); 372 } 373 374 375 376 // ---------------------------------------------------------------------------- 377 378 DBG_NAME( ScAccessibleCsvRuler ) 379 380 ScAccessibleCsvRuler::ScAccessibleCsvRuler( ScCsvRuler& rRuler ) : 381 ScAccessibleCsvControl( rRuler.GetAccessibleParentWindow()->GetAccessible(), rRuler, nRulerRole ) 382 { 383 DBG_CTOR( ScAccessibleCsvRuler, NULL ); 384 constructStringBuffer(); 385 } 386 387 ScAccessibleCsvRuler::~ScAccessibleCsvRuler() 388 { 389 DBG_DTOR( ScAccessibleCsvRuler, NULL ); 390 implDispose(); 391 } 392 393 // XAccessibleComponent ----------------------------------------------------- 394 395 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getForeground( ) 396 throw (RuntimeException) 397 { 398 ScUnoGuard aGuard; 399 ensureAlive(); 400 return implGetRuler().GetSettings().GetStyleSettings().GetLabelTextColor().GetColor(); 401 } 402 403 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getBackground( ) 404 throw (RuntimeException) 405 { 406 ScUnoGuard aGuard; 407 ensureAlive(); 408 return implGetRuler().GetSettings().GetStyleSettings().GetFaceColor().GetColor(); 409 } 410 411 // XAccessibleContext --------------------------------------------------------- 412 413 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getAccessibleChildCount() throw( RuntimeException ) 414 { 415 ensureAlive(); 416 return 0; 417 } 418 419 Reference< XAccessible > SAL_CALL ScAccessibleCsvRuler::getAccessibleChild( sal_Int32 /* nIndex */ ) 420 throw( IndexOutOfBoundsException, RuntimeException ) 421 { 422 ensureAlive(); 423 throw IndexOutOfBoundsException(); 424 } 425 426 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvRuler::getAccessibleRelationSet() 427 throw( RuntimeException ) 428 { 429 ScUnoGuard aGuard; 430 ensureAlive(); 431 AccessibleRelationSetHelper* pRelationSet = new AccessibleRelationSetHelper(); 432 Reference< XAccessible > xAccObj = implGetChildByRole( getAccessibleParent(), nGridRole ); 433 if( xAccObj.is() ) 434 { 435 Sequence< Reference< XInterface > > aSeq( 1 ); 436 aSeq[ 0 ] = xAccObj; 437 pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::CONTROLLER_FOR, aSeq ) ); 438 } 439 return pRelationSet; 440 } 441 442 Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvRuler::getAccessibleStateSet() 443 throw( RuntimeException ) 444 { 445 ScUnoGuard aGuard; 446 AccessibleStateSetHelper* pStateSet = implCreateStateSet(); 447 if( implIsAlive() ) 448 { 449 pStateSet->AddState( AccessibleStateType::FOCUSABLE ); 450 pStateSet->AddState( AccessibleStateType::SINGLE_LINE ); 451 if( implGetRuler().HasFocus() ) 452 pStateSet->AddState( AccessibleStateType::FOCUSED ); 453 } 454 return pStateSet; 455 } 456 457 458 // XAccessibleText ------------------------------------------------------------ 459 460 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCaretPosition() throw( RuntimeException ) 461 { 462 ScUnoGuard aGuard; 463 ensureAlive(); 464 return lcl_GetApiPos( implGetRuler().GetRulerCursorPos() ); 465 } 466 467 sal_Bool SAL_CALL ScAccessibleCsvRuler::setCaretPosition( sal_Int32 nIndex ) 468 throw( IndexOutOfBoundsException, RuntimeException ) 469 { 470 ScUnoGuard aGuard; 471 ensureAlive(); 472 ensureValidIndex( nIndex ); 473 ScCsvRuler& rRuler = implGetRuler(); 474 sal_Int32 nOldCursor = rRuler.GetRulerCursorPos(); 475 rRuler.Execute( CSVCMD_MOVERULERCURSOR, lcl_GetRulerPos( nIndex ) ); 476 return rRuler.GetRulerCursorPos() != nOldCursor; 477 } 478 479 sal_Unicode SAL_CALL ScAccessibleCsvRuler::getCharacter( sal_Int32 nIndex ) 480 throw( IndexOutOfBoundsException, RuntimeException ) 481 { 482 ScUnoGuard aGuard; 483 ensureAlive(); 484 ensureValidIndex( nIndex ); 485 return maBuffer.charAt( nIndex ); 486 } 487 488 Sequence< PropertyValue > SAL_CALL ScAccessibleCsvRuler::getCharacterAttributes( sal_Int32 nIndex, 489 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& /* aRequestedAttributes */ ) 490 throw( IndexOutOfBoundsException, RuntimeException ) 491 { 492 ScUnoGuard aGuard; 493 ensureAlive(); 494 ensureValidIndexWithEnd( nIndex ); 495 Sequence< PropertyValue > aSeq; 496 lcl_FillFontAttributes( aSeq, implGetRuler().GetFont() ); 497 //! TODO split attribute: waiting for #102221# 498 // if( implHasSplit( nIndex ) ) 499 // { 500 // sal_Int32 nIndex = lcl_ExpandSequence( aSeq, 1 ); 501 // aSeq[ nIndex ].Name = CREATE_OUSTRING( "..." ); 502 // aSeq[ nIndex ].Value <<= ...; 503 // } 504 return aSeq; 505 } 506 507 ScAccessibleCsvRuler::AwtRectangle SAL_CALL ScAccessibleCsvRuler::getCharacterBounds( sal_Int32 nIndex ) 508 throw( IndexOutOfBoundsException, RuntimeException ) 509 { 510 ScUnoGuard aGuard; 511 ensureAlive(); 512 ensureValidIndexWithEnd( nIndex ); 513 ScCsvRuler& rRuler = implGetRuler(); 514 Point aPos( rRuler.GetX( lcl_GetRulerPos( nIndex ) ) - rRuler.GetCharWidth() / 2, 0 ); 515 AwtRectangle aRect( aPos.X(), aPos.Y(), rRuler.GetCharWidth(), rRuler.GetSizePixel().Height() ); 516 // #107054# do not return rectangle out of window 517 sal_Int32 nWidth = rRuler.GetOutputSizePixel().Width(); 518 if( aRect.X >= nWidth ) 519 throw IndexOutOfBoundsException(); 520 if( aRect.X + aRect.Width > nWidth ) 521 aRect.Width = nWidth - aRect.X; 522 return aRect; 523 } 524 525 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCharacterCount() throw( RuntimeException ) 526 { 527 ScUnoGuard aGuard; 528 ensureAlive(); 529 return implGetTextLength(); 530 } 531 532 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getIndexAtPoint( const AwtPoint& rPoint ) 533 throw( RuntimeException ) 534 { 535 ScUnoGuard aGuard; 536 ensureAlive(); 537 ScCsvRuler& rRuler = implGetRuler(); 538 // #107054# use object's coordinate system, convert to API position 539 return lcl_GetApiPos( ::std::min( ::std::max( rRuler.GetPosFromX( rPoint.X ), static_cast<sal_Int32>(0) ), rRuler.GetPosCount() ) ); 540 } 541 542 OUString SAL_CALL ScAccessibleCsvRuler::getSelectedText() throw( RuntimeException ) 543 { 544 ensureAlive(); 545 return OUString(); 546 } 547 548 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionStart() throw( RuntimeException ) 549 { 550 ensureAlive(); 551 return -1; 552 } 553 554 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionEnd() throw( RuntimeException ) 555 { 556 ensureAlive(); 557 return -1; 558 } 559 560 sal_Bool SAL_CALL ScAccessibleCsvRuler::setSelection( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ ) 561 throw( IndexOutOfBoundsException, RuntimeException ) 562 { 563 ensureAlive(); 564 return sal_False; 565 } 566 567 OUString SAL_CALL ScAccessibleCsvRuler::getText() throw( RuntimeException ) 568 { 569 ScUnoGuard aGuard; 570 ensureAlive(); 571 return OUString( maBuffer.getStr(), implGetTextLength() ); 572 } 573 574 OUString SAL_CALL ScAccessibleCsvRuler::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) 575 throw( IndexOutOfBoundsException, RuntimeException ) 576 { 577 ScUnoGuard aGuard; 578 ensureAlive(); 579 ensureValidRange( nStartIndex, nEndIndex ); 580 return OUString( maBuffer.getStr() + nStartIndex, nEndIndex - nStartIndex ); 581 } 582 583 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextAtIndex( sal_Int32 nIndex, sal_Int16 nTextType ) 584 throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException ) 585 { 586 ScUnoGuard aGuard; 587 ensureAlive(); 588 589 TextSegment aResult; 590 aResult.SegmentStart = -1; 591 aResult.SegmentEnd = -1; 592 593 if( (nIndex == implGetTextLength()) && (nTextType != AccessibleTextType::LINE) ) 594 return aResult; 595 596 ensureValidIndex( nIndex ); 597 598 OUStringBuffer aResultText; // will be assigned to aResult.SegmentText below 599 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex ); 600 601 switch( nTextType ) 602 { 603 // single character 604 case AccessibleTextType::CHARACTER: 605 { 606 aResult.SegmentStart = nIndex; 607 aResultText.append( maBuffer.charAt( nIndex ) ); 608 } 609 break; 610 611 // entire number or single dot/line 612 case AccessibleTextType::WORD: 613 case AccessibleTextType::GLYPH: 614 aResult.SegmentStart = nIndex; 615 if( nRulerPos % 10 ) 616 aResultText.append( maBuffer.charAt( nIndex ) ); 617 else 618 aResultText.append( nRulerPos ); // string representation of sal_Int32!!! 619 break; 620 621 // entire text 622 case AccessibleTextType::SENTENCE: 623 case AccessibleTextType::PARAGRAPH: 624 case AccessibleTextType::LINE: 625 aResult.SegmentStart = 0; 626 aResultText.append( maBuffer.getStr(), implGetTextLength() ); 627 break; 628 629 // equal-formatted text 630 case AccessibleTextType::ATTRIBUTE_RUN: 631 { 632 sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex ); 633 sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex ); 634 aResult.SegmentStart = nFirstIndex; 635 aResultText.append( maBuffer.getStr() + nFirstIndex, nLastIndex - nFirstIndex + 1 ); 636 } 637 break; 638 639 default: 640 throw RuntimeException(); 641 } 642 643 aResult.SegmentText = aResultText.makeStringAndClear(); 644 aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength(); 645 return aResult; 646 } 647 648 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 nTextType ) 649 throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException ) 650 { 651 ScUnoGuard aGuard; 652 ensureAlive(); 653 ensureValidIndexWithEnd( nIndex ); 654 655 TextSegment aResult; 656 aResult.SegmentStart = -1; 657 aResult.SegmentEnd = -1; 658 659 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex ); 660 661 switch( nTextType ) 662 { 663 // single character 664 case AccessibleTextType::CHARACTER: 665 if( nIndex > 0 ) 666 aResult = getTextAtIndex( nIndex - 1, nTextType ); 667 // else empty 668 break; 669 670 // entire number or single dot/line 671 case AccessibleTextType::WORD: 672 case AccessibleTextType::GLYPH: 673 if( nRulerPos > 0 ) 674 aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos - 1 ), nTextType ); 675 // else empty 676 break; 677 678 // entire text 679 case AccessibleTextType::SENTENCE: 680 case AccessibleTextType::PARAGRAPH: 681 case AccessibleTextType::LINE: 682 // empty 683 break; 684 685 // equal-formatted text 686 case AccessibleTextType::ATTRIBUTE_RUN: 687 { 688 sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex ); 689 if( nFirstIndex > 0 ) 690 aResult = getTextAtIndex( nFirstIndex - 1, nTextType ); 691 // else empty 692 } 693 break; 694 695 default: 696 throw RuntimeException(); 697 } 698 return aResult; 699 } 700 701 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 nTextType ) 702 throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException ) 703 { 704 ScUnoGuard aGuard; 705 ensureAlive(); 706 ensureValidIndexWithEnd( nIndex ); 707 708 TextSegment aResult; 709 aResult.SegmentStart = -1; 710 aResult.SegmentEnd = -1; 711 712 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex ); 713 sal_Int32 nLastValid = implGetTextLength(); 714 715 switch( nTextType ) 716 { 717 // single character 718 case AccessibleTextType::CHARACTER: 719 if( nIndex < nLastValid ) 720 aResult = getTextAtIndex( nIndex + 1, nTextType ); 721 // else empty 722 break; 723 724 // entire number or single dot/line 725 case AccessibleTextType::WORD: 726 case AccessibleTextType::GLYPH: 727 if( nRulerPos < implGetRuler().GetPosCount() ) 728 aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos + 1 ), nTextType ); 729 // else empty 730 break; 731 732 // entire text 733 case AccessibleTextType::SENTENCE: 734 case AccessibleTextType::PARAGRAPH: 735 case AccessibleTextType::LINE: 736 // empty 737 break; 738 739 // equal-formatted text 740 case AccessibleTextType::ATTRIBUTE_RUN: 741 { 742 sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex ); 743 if( nLastIndex < nLastValid ) 744 aResult = getTextAtIndex( nLastIndex + 1, nTextType ); 745 // else empty 746 } 747 break; 748 749 default: 750 throw RuntimeException(); 751 } 752 return aResult; 753 } 754 755 sal_Bool SAL_CALL ScAccessibleCsvRuler::copyText( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ ) 756 throw( IndexOutOfBoundsException, RuntimeException ) 757 { 758 ensureAlive(); 759 return sal_False; 760 } 761 762 763 // XInterface ----------------------------------------------------------------- 764 765 Any SAL_CALL ScAccessibleCsvRuler::queryInterface( const ::com::sun::star::uno::Type& rType ) 766 throw( RuntimeException ) 767 { 768 Any aAny( ScAccessibleCsvRulerImpl::queryInterface( rType ) ); 769 return aAny.hasValue() ? aAny : ScAccessibleCsvControl::queryInterface( rType ); 770 } 771 772 void SAL_CALL ScAccessibleCsvRuler::acquire() throw () 773 { 774 ScAccessibleCsvControl::acquire(); 775 } 776 777 void SAL_CALL ScAccessibleCsvRuler::release() throw () 778 { 779 ScAccessibleCsvControl::release(); 780 } 781 782 783 // XServiceInfo --------------------------------------------------------------- 784 785 OUString SAL_CALL ScAccessibleCsvRuler::getImplementationName() throw( RuntimeException ) 786 { 787 return CREATE_OUSTRING( RULER_IMPL_NAME ); 788 } 789 790 791 // XTypeProvider -------------------------------------------------------------- 792 793 Sequence< ::com::sun::star::uno::Type > SAL_CALL ScAccessibleCsvRuler::getTypes() throw( RuntimeException ) 794 { 795 Sequence< ::com::sun::star::uno::Type > aSeq( 1 ); 796 aSeq[ 0 ] = getCppuType( static_cast< const Reference< XAccessibleText >* >( NULL ) ); 797 return ::comphelper::concatSequences( ScAccessibleCsvControl::getTypes(), aSeq ); 798 } 799 800 Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvRuler::getImplementationId() throw( RuntimeException ) 801 { 802 static Sequence< sal_Int8 > aSeq; 803 getUuid( aSeq ); 804 return aSeq; 805 } 806 807 808 // events --------------------------------------------------------------------- 809 810 void ScAccessibleCsvRuler::SendCaretEvent() 811 { 812 sal_Int32 nPos = implGetRuler().GetRulerCursorPos(); 813 if( nPos != CSV_POS_INVALID ) 814 { 815 AccessibleEventObject aEvent; 816 aEvent.EventId = AccessibleEventId::CARET_CHANGED; 817 aEvent.Source = Reference< XAccessible >( this ); 818 aEvent.NewValue <<= nPos; 819 CommitChange( aEvent ); 820 } 821 } 822 823 824 // helpers -------------------------------------------------------------------- 825 826 OUString SAL_CALL ScAccessibleCsvRuler::createAccessibleName() throw( RuntimeException ) 827 { 828 return String( ScResId( STR_ACC_CSVRULER_NAME ) ); 829 } 830 831 OUString SAL_CALL ScAccessibleCsvRuler::createAccessibleDescription() throw( RuntimeException ) 832 { 833 return String( ScResId( STR_ACC_CSVRULER_DESCR ) ); 834 } 835 836 void ScAccessibleCsvRuler::ensureValidIndex( sal_Int32 nIndex ) const 837 throw( IndexOutOfBoundsException ) 838 { 839 if( (nIndex < 0) || (nIndex >= implGetTextLength()) ) 840 throw IndexOutOfBoundsException(); 841 } 842 843 void ScAccessibleCsvRuler::ensureValidIndexWithEnd( sal_Int32 nIndex ) const 844 throw( IndexOutOfBoundsException ) 845 { 846 if( (nIndex < 0) || (nIndex > implGetTextLength()) ) 847 throw IndexOutOfBoundsException(); 848 } 849 850 void ScAccessibleCsvRuler::ensureValidRange( sal_Int32& rnStartIndex, sal_Int32& rnEndIndex ) const 851 throw( IndexOutOfBoundsException ) 852 { 853 if( rnStartIndex > rnEndIndex ) 854 ::std::swap( rnStartIndex, rnEndIndex ); 855 if( (rnStartIndex < 0) || (rnEndIndex > implGetTextLength()) ) 856 throw IndexOutOfBoundsException(); 857 } 858 859 ScCsvRuler& ScAccessibleCsvRuler::implGetRuler() const 860 { 861 return static_cast< ScCsvRuler& >( implGetControl() ); 862 } 863 864 void ScAccessibleCsvRuler::constructStringBuffer() throw( RuntimeException ) 865 { 866 ScUnoGuard aGuard; 867 ensureAlive(); 868 // extend existing string buffer to new ruler size 869 sal_Int32 nRulerCount = implGetRuler().GetPosCount(); 870 sal_Int32 nRulerPos = lcl_GetRulerPos( maBuffer.getLength() ); 871 for( ; nRulerPos <= nRulerCount; ++nRulerPos ) // include last position 872 { 873 switch( nRulerPos % 10 ) 874 { 875 case 0: maBuffer.append( nRulerPos ); break; 876 case 5: maBuffer.append( cRulerLine ); break; 877 default: maBuffer.append( cRulerDot ); 878 } 879 } 880 } 881 882 sal_Int32 ScAccessibleCsvRuler::implGetTextLength() const 883 { 884 return lcl_GetApiPos( implGetRuler().GetPosCount() + 1 ); 885 } 886 887 bool ScAccessibleCsvRuler::implHasSplit( sal_Int32 nApiPos ) 888 { 889 sal_Int32 nRulerPos = lcl_GetRulerPos( nApiPos ); 890 return implGetRuler().HasSplit( nRulerPos ) && (nApiPos == lcl_GetApiPos( nRulerPos )); 891 } 892 893 sal_Int32 ScAccessibleCsvRuler::implGetFirstEqualFormatted( sal_Int32 nApiPos ) 894 { 895 bool bSplit = implHasSplit( nApiPos ); 896 while( (nApiPos > 0) && (implHasSplit( nApiPos - 1 ) == bSplit) ) 897 --nApiPos; 898 return nApiPos; 899 } 900 901 sal_Int32 ScAccessibleCsvRuler::implGetLastEqualFormatted( sal_Int32 nApiPos ) 902 { 903 bool bSplit = implHasSplit( nApiPos ); 904 sal_Int32 nLength = implGetTextLength(); 905 while( (nApiPos < nLength - 1) && (implHasSplit( nApiPos + 1 ) == bSplit) ) 906 ++nApiPos; 907 return nApiPos; 908 } 909 910 911 // Grid ======================================================================= 912 913 /** Converts a grid columnm index to an API column index. */ 914 inline sal_Int32 lcl_GetApiColumn( sal_uInt32 nGridColumn ) 915 { 916 return (nGridColumn != CSV_COLUMN_HEADER) ? static_cast< sal_Int32 >( nGridColumn + 1 ) : 0; 917 } 918 919 /** Converts an API columnm index to a ScCsvGrid column index. */ 920 inline sal_uInt32 lcl_GetGridColumn( sal_Int32 nApiColumn ) 921 { 922 return (nApiColumn > 0) ? static_cast< sal_uInt32 >( nApiColumn - 1 ) : CSV_COLUMN_HEADER; 923 } 924 925 926 // ---------------------------------------------------------------------------- 927 928 DBG_NAME( ScAccessibleCsvGrid ) 929 930 ScAccessibleCsvGrid::ScAccessibleCsvGrid( ScCsvGrid& rGrid ) : 931 ScAccessibleCsvControl( rGrid.GetAccessibleParentWindow()->GetAccessible(), rGrid, nGridRole ) 932 { 933 DBG_CTOR( ScAccessibleCsvGrid, NULL ); 934 } 935 936 ScAccessibleCsvGrid::~ScAccessibleCsvGrid() 937 { 938 DBG_DTOR( ScAccessibleCsvGrid, NULL ); 939 implDispose(); 940 } 941 942 943 // XAccessibleComponent ------------------------------------------------------- 944 945 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleAtPoint( const AwtPoint& rPoint ) 946 throw( RuntimeException ) 947 { 948 Reference< XAccessible > xRet; 949 if( containsPoint( rPoint ) ) 950 { 951 ScUnoGuard aGuard; 952 ensureAlive(); 953 954 const ScCsvGrid& rGrid = implGetGrid(); 955 // #102679#; use <= instead of <, because the offset is the size and not the point 956 sal_Int32 nColumn = ((rGrid.GetFirstX() <= rPoint.X) && (rPoint.X <= rGrid.GetLastX())) ? 957 lcl_GetApiColumn( rGrid.GetColumnFromX( rPoint.X ) ) : 0; 958 sal_Int32 nRow = (rPoint.Y >= rGrid.GetHdrHeight()) ? 959 (rGrid.GetLineFromY( rPoint.Y ) - rGrid.GetFirstVisLine() + 1) : 0; 960 xRet = implCreateCellObj( nRow, nColumn ); 961 } 962 return xRet; 963 } 964 965 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getForeground( ) 966 throw (RuntimeException) 967 { 968 ScUnoGuard aGuard; 969 ensureAlive(); 970 return implGetGrid().GetSettings().GetStyleSettings().GetButtonTextColor().GetColor(); 971 } 972 973 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getBackground( ) 974 throw (RuntimeException) 975 { 976 ScUnoGuard aGuard; 977 ensureAlive(); 978 return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor; 979 } 980 981 // XAccessibleContext --------------------------------------------------------- 982 983 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleChildCount() throw( RuntimeException ) 984 { 985 ScUnoGuard aGuard; 986 ensureAlive(); 987 return implGetCellCount(); 988 } 989 990 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleChild( sal_Int32 nIndex ) 991 throw( IndexOutOfBoundsException, RuntimeException ) 992 { 993 ScUnoGuard aGuard; 994 ensureAlive(); 995 ensureValidIndex( nIndex ); 996 return implCreateCellObj( implGetRow( nIndex ), implGetColumn( nIndex ) ); 997 } 998 999 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleRelationSet() 1000 throw( RuntimeException ) 1001 { 1002 ScUnoGuard aGuard; 1003 ensureAlive(); 1004 AccessibleRelationSetHelper* pRelationSet = new AccessibleRelationSetHelper(); 1005 Reference< XAccessible > xAccObj = implGetChildByRole( getAccessibleParent(), nRulerRole ); 1006 if( xAccObj.is() ) 1007 { 1008 Sequence< Reference< XInterface > > aSeq( 1 ); 1009 aSeq[ 0 ] = xAccObj; 1010 pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::CONTROLLED_BY, aSeq ) ); 1011 } 1012 return pRelationSet; 1013 } 1014 1015 Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleStateSet() 1016 throw( RuntimeException ) 1017 { 1018 ScUnoGuard aGuard; 1019 AccessibleStateSetHelper* pStateSet = implCreateStateSet(); 1020 if( implIsAlive() ) 1021 { 1022 pStateSet->AddState( AccessibleStateType::FOCUSABLE ); 1023 pStateSet->AddState( AccessibleStateType::MULTI_SELECTABLE ); 1024 pStateSet->AddState( AccessibleStateType::MANAGES_DESCENDANTS ); 1025 if( implGetGrid().HasFocus() ) 1026 pStateSet->AddState( AccessibleStateType::FOCUSED ); 1027 } 1028 else 1029 pStateSet->AddState( AccessibleStateType::DEFUNC ); 1030 return pStateSet; 1031 } 1032 1033 1034 // XAccessibleTable ----------------------------------------------------------- 1035 1036 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowCount() throw( RuntimeException ) 1037 { 1038 ScUnoGuard aGuard; 1039 ensureAlive(); 1040 return implGetRowCount(); 1041 } 1042 1043 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnCount() throw( RuntimeException ) 1044 { 1045 ScUnoGuard aGuard; 1046 ensureAlive(); 1047 return implGetColumnCount(); 1048 } 1049 1050 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleRowDescription( sal_Int32 nRow ) 1051 throw( IndexOutOfBoundsException, RuntimeException ) 1052 { 1053 ScUnoGuard aGuard; 1054 ensureAlive(); 1055 ensureValidPosition( nRow, 0 ); 1056 return implGetCellText( nRow, 0 ); 1057 } 1058 1059 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnDescription( sal_Int32 nColumn ) 1060 throw( IndexOutOfBoundsException, RuntimeException ) 1061 { 1062 ScUnoGuard aGuard; 1063 ensureAlive(); 1064 ensureValidPosition( 0, nColumn ); 1065 return implGetCellText( 0, nColumn ); 1066 } 1067 1068 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) 1069 throw( IndexOutOfBoundsException, RuntimeException ) 1070 { 1071 ensureAlive(); 1072 ensureValidPosition( nRow, nColumn ); 1073 return 1; 1074 } 1075 1076 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) 1077 throw( IndexOutOfBoundsException, RuntimeException ) 1078 { 1079 ensureAlive(); 1080 ensureValidPosition( nRow, nColumn ); 1081 return 1; 1082 } 1083 1084 Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleRowHeaders() 1085 throw( RuntimeException ) 1086 { 1087 ensureAlive(); 1088 return NULL; 1089 } 1090 1091 Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnHeaders() 1092 throw( RuntimeException ) 1093 { 1094 ensureAlive(); 1095 return NULL; 1096 } 1097 1098 Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleRows() 1099 throw( RuntimeException ) 1100 { 1101 ensureAlive(); 1102 return Sequence< sal_Int32 >(); 1103 } 1104 1105 Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleColumns() 1106 throw( RuntimeException ) 1107 { 1108 ScUnoGuard aGuard; 1109 ensureAlive(); 1110 1111 ScCsvGrid& rGrid = implGetGrid(); 1112 Sequence< sal_Int32 > aSeq( implGetColumnCount() ); 1113 1114 sal_Int32 nSeqIx = 0; 1115 sal_uInt32 nColIx = rGrid.GetFirstSelected(); 1116 for( ; nColIx != CSV_COLUMN_INVALID; ++nSeqIx, nColIx = rGrid.GetNextSelected( nColIx ) ) 1117 aSeq[ nSeqIx ] = lcl_GetApiColumn( nColIx ); 1118 1119 aSeq.realloc( nSeqIx ); 1120 return aSeq; 1121 } 1122 1123 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleRowSelected( sal_Int32 /* nRow */ ) 1124 throw( IndexOutOfBoundsException, RuntimeException ) 1125 { 1126 ensureAlive(); 1127 return sal_False; 1128 } 1129 1130 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleColumnSelected( sal_Int32 nColumn ) 1131 throw( IndexOutOfBoundsException, RuntimeException ) 1132 { 1133 ScUnoGuard aGuard; 1134 ensureAlive(); 1135 ensureValidIndex( nColumn ); 1136 return implIsColumnSelected( nColumn ); 1137 } 1138 1139 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn ) 1140 throw( IndexOutOfBoundsException, RuntimeException ) 1141 { 1142 ScUnoGuard aGuard; 1143 ensureAlive(); 1144 ensureValidPosition( nRow, nColumn ); 1145 return implCreateCellObj( nRow, nColumn ); 1146 } 1147 1148 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCaption() 1149 throw( RuntimeException ) 1150 { 1151 ensureAlive(); 1152 return NULL; 1153 } 1154 1155 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleSummary() 1156 throw( RuntimeException ) 1157 { 1158 ensureAlive(); 1159 return NULL; 1160 } 1161 1162 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 nColumn ) 1163 throw( IndexOutOfBoundsException, RuntimeException ) 1164 { 1165 return isAccessibleColumnSelected( nColumn ); 1166 } 1167 1168 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn ) 1169 throw( IndexOutOfBoundsException, RuntimeException ) 1170 { 1171 ScUnoGuard aGuard; 1172 ensureAlive(); 1173 ensureValidPosition( nRow, nColumn ); 1174 return implGetIndex( nRow, nColumn ); 1175 } 1176 1177 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRow( sal_Int32 nChildIndex ) 1178 throw( IndexOutOfBoundsException, RuntimeException ) 1179 { 1180 ScUnoGuard aGuard; 1181 ensureAlive(); 1182 ensureValidIndex( nChildIndex ); 1183 return implGetRow( nChildIndex ); 1184 } 1185 1186 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumn( sal_Int32 nChildIndex ) 1187 throw( IndexOutOfBoundsException, RuntimeException ) 1188 { 1189 ScUnoGuard aGuard; 1190 ensureAlive(); 1191 ensureValidIndex( nChildIndex ); 1192 return implGetColumn( nChildIndex ); 1193 } 1194 1195 1196 // XAccessibleSelection ------------------------------------------------------- 1197 1198 void SAL_CALL ScAccessibleCsvGrid::selectAccessibleChild( sal_Int32 nChildIndex ) 1199 throw( IndexOutOfBoundsException, RuntimeException ) 1200 { 1201 ScUnoGuard aGuard; 1202 ensureAlive(); 1203 ensureValidIndex( nChildIndex ); 1204 sal_Int32 nColumn = implGetColumn( nChildIndex ); 1205 if( nChildIndex == 0 ) 1206 implGetGrid().SelectAll(); 1207 else 1208 implSelectColumn( nColumn, true ); 1209 } 1210 1211 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleChildSelected( sal_Int32 nChildIndex ) 1212 throw( IndexOutOfBoundsException, RuntimeException ) 1213 { 1214 ScUnoGuard aGuard; 1215 ensureAlive(); 1216 ensureValidIndex( nChildIndex ); 1217 sal_Int32 nColumn = implGetColumn( nChildIndex ); 1218 return implIsColumnSelected( nColumn ); 1219 } 1220 1221 void SAL_CALL ScAccessibleCsvGrid::clearAccessibleSelection() throw( RuntimeException ) 1222 { 1223 ScUnoGuard aGuard; 1224 ensureAlive(); 1225 implGetGrid().SelectAll( false ); 1226 } 1227 1228 void SAL_CALL ScAccessibleCsvGrid::selectAllAccessibleChildren() throw( RuntimeException ) 1229 { 1230 selectAccessibleChild( 0 ); 1231 } 1232 1233 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChildCount() throw( RuntimeException ) 1234 { 1235 ScUnoGuard aGuard; 1236 ensureAlive(); 1237 return implGetRowCount() * implGetSelColumnCount(); 1238 } 1239 1240 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) 1241 throw( IndexOutOfBoundsException, RuntimeException ) 1242 { 1243 ScUnoGuard aGuard; 1244 ensureAlive(); 1245 sal_Int32 nColumns = implGetSelColumnCount(); 1246 if( nColumns == 0 ) 1247 throw IndexOutOfBoundsException(); 1248 1249 sal_Int32 nRow = nSelectedChildIndex / nColumns; 1250 sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns ); 1251 return getAccessibleCellAt( nRow, nColumn ); 1252 } 1253 1254 void SAL_CALL ScAccessibleCsvGrid::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) 1255 throw( IndexOutOfBoundsException, RuntimeException ) 1256 { 1257 ScUnoGuard aGuard; 1258 ensureAlive(); 1259 sal_Int32 nColumns = implGetSelColumnCount(); 1260 if( nColumns == 0 ) 1261 throw IndexOutOfBoundsException(); 1262 1263 sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns ); 1264 ensureValidPosition( nSelectedChildIndex / nColumns, nColumn ); 1265 if( nColumn > 0 ) 1266 implSelectColumn( nColumn, false ); 1267 } 1268 1269 1270 // XInterface ----------------------------------------------------------------- 1271 1272 Any SAL_CALL ScAccessibleCsvGrid::queryInterface( const ::com::sun::star::uno::Type& rType ) 1273 throw( RuntimeException ) 1274 { 1275 Any aAny( ScAccessibleCsvGridImpl::queryInterface( rType ) ); 1276 return aAny.hasValue() ? aAny : ScAccessibleCsvControl::queryInterface( rType ); 1277 } 1278 1279 void SAL_CALL ScAccessibleCsvGrid::acquire() throw () 1280 { 1281 ScAccessibleCsvControl::acquire(); 1282 } 1283 1284 void SAL_CALL ScAccessibleCsvGrid::release() throw () 1285 { 1286 ScAccessibleCsvControl::release(); 1287 } 1288 1289 1290 // XServiceInfo --------------------------------------------------------------- 1291 1292 OUString SAL_CALL ScAccessibleCsvGrid::getImplementationName() throw( RuntimeException ) 1293 { 1294 return CREATE_OUSTRING( GRID_IMPL_NAME ); 1295 } 1296 1297 1298 // XTypeProvider -------------------------------------------------------------- 1299 1300 Sequence< ::com::sun::star::uno::Type > SAL_CALL ScAccessibleCsvGrid::getTypes() throw( RuntimeException ) 1301 { 1302 Sequence< ::com::sun::star::uno::Type > aSeq( 2 ); 1303 aSeq[ 0 ] = getCppuType( static_cast< const Reference< XAccessibleTable >* >( NULL ) ); 1304 aSeq[ 1 ] = getCppuType( static_cast< const Reference< XAccessibleSelection >* >( NULL ) ); 1305 return ::comphelper::concatSequences( ScAccessibleCsvControl::getTypes(), aSeq ); 1306 } 1307 1308 Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvGrid::getImplementationId() throw( RuntimeException ) 1309 { 1310 static Sequence< sal_Int8 > aSeq; 1311 getUuid( aSeq ); 1312 return aSeq; 1313 } 1314 1315 1316 // events --------------------------------------------------------------------- 1317 1318 void ScAccessibleCsvGrid::SendFocusEvent( bool bFocused ) 1319 { 1320 ScAccessibleCsvControl::SendFocusEvent( bFocused ); 1321 1322 AccessibleEventObject aEvent; 1323 aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED; 1324 aEvent.Source = Reference< XAccessible >( this ); 1325 (bFocused ? aEvent.NewValue : aEvent.OldValue) <<= 1326 getAccessibleCellAt( 0, lcl_GetApiColumn( implGetGrid().GetFocusColumn() ) ); 1327 CommitChange( aEvent ); 1328 } 1329 1330 void ScAccessibleCsvGrid::SendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows ) 1331 { 1332 if( nFirstColumn <= nLastColumn ) 1333 { 1334 AccessibleTableModelChange aModelChange( 1335 AccessibleTableModelChangeType::UPDATE, 0, bAllRows ? implGetRowCount() - 1 : 0, 1336 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) ); 1337 AccessibleEventObject aEvent; 1338 aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED; 1339 aEvent.Source = Reference< XAccessible >( this ); 1340 aEvent.NewValue <<= aModelChange; 1341 CommitChange( aEvent ); 1342 } 1343 } 1344 1345 void ScAccessibleCsvGrid::SendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn ) 1346 { 1347 if( nFirstColumn <= nLastColumn ) 1348 { 1349 AccessibleTableModelChange aModelChange( 1350 AccessibleTableModelChangeType::INSERT, 0, implGetRowCount() - 1, 1351 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) ); 1352 AccessibleEventObject aEvent; 1353 aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED; 1354 aEvent.Source = Reference< XAccessible >( this ); 1355 aEvent.NewValue <<= aModelChange; 1356 CommitChange( aEvent ); 1357 } 1358 } 1359 1360 void ScAccessibleCsvGrid::SendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn ) 1361 { 1362 if( nFirstColumn <= nLastColumn ) 1363 { 1364 AccessibleTableModelChange aModelChange( 1365 AccessibleTableModelChangeType::DELETE, 0, implGetRowCount() - 1, 1366 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) ); 1367 AccessibleEventObject aEvent; 1368 aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED; 1369 aEvent.Source = Reference< XAccessible >( this ); 1370 aEvent.NewValue <<= aModelChange; 1371 CommitChange( aEvent ); 1372 } 1373 } 1374 1375 1376 // helpers -------------------------------------------------------------------- 1377 1378 OUString SAL_CALL ScAccessibleCsvGrid::createAccessibleName() throw( RuntimeException ) 1379 { 1380 return String( ScResId( STR_ACC_CSVGRID_NAME ) ); 1381 } 1382 1383 OUString SAL_CALL ScAccessibleCsvGrid::createAccessibleDescription() throw( RuntimeException ) 1384 { 1385 return String( ScResId( STR_ACC_CSVGRID_DESCR ) ); 1386 } 1387 1388 void ScAccessibleCsvGrid::ensureValidIndex( sal_Int32 nIndex ) const 1389 throw( IndexOutOfBoundsException ) 1390 { 1391 if( (nIndex < 0) || (nIndex >= implGetCellCount()) ) 1392 throw IndexOutOfBoundsException(); 1393 } 1394 1395 void ScAccessibleCsvGrid::ensureValidPosition( sal_Int32 nRow, sal_Int32 nColumn ) const 1396 throw( IndexOutOfBoundsException ) 1397 { 1398 if( (nRow < 0) || (nRow >= implGetRowCount()) || (nColumn < 0) || (nColumn >= implGetColumnCount()) ) 1399 throw IndexOutOfBoundsException(); 1400 } 1401 1402 ScCsvGrid& ScAccessibleCsvGrid::implGetGrid() const 1403 { 1404 return static_cast< ScCsvGrid& >( implGetControl() ); 1405 } 1406 1407 bool ScAccessibleCsvGrid::implIsColumnSelected( sal_Int32 nColumn ) const 1408 { 1409 return (nColumn > 0) && implGetGrid().IsSelected( lcl_GetGridColumn( nColumn ) ); 1410 } 1411 1412 void ScAccessibleCsvGrid::implSelectColumn( sal_Int32 nColumn, bool bSelect ) 1413 { 1414 if( nColumn > 0 ) 1415 implGetGrid().Select( lcl_GetGridColumn( nColumn ), bSelect ); 1416 } 1417 1418 sal_Int32 ScAccessibleCsvGrid::implGetRowCount() const 1419 { 1420 return static_cast< sal_Int32 >( implGetGrid().GetLastVisLine() - implGetGrid().GetFirstVisLine() + 2 ); 1421 } 1422 1423 sal_Int32 ScAccessibleCsvGrid::implGetColumnCount() const 1424 { 1425 return static_cast< sal_Int32 >( implGetGrid().GetColumnCount() + 1 ); 1426 } 1427 1428 sal_Int32 ScAccessibleCsvGrid::implGetSelColumnCount() const 1429 { 1430 ScCsvGrid& rGrid = implGetGrid(); 1431 sal_Int32 nCount = 0; 1432 for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) ) 1433 ++nCount; 1434 return nCount; 1435 } 1436 1437 sal_Int32 ScAccessibleCsvGrid::implGetSelColumn( sal_Int32 nSelColumn ) const 1438 { 1439 ScCsvGrid& rGrid = implGetGrid(); 1440 sal_Int32 nColumn = 0; 1441 for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) ) 1442 { 1443 if( nColumn == nSelColumn ) 1444 return static_cast< sal_Int32 >( nColIx + 1 ); 1445 ++nColumn; 1446 } 1447 return 0; 1448 } 1449 1450 String ScAccessibleCsvGrid::implGetCellText( sal_Int32 nRow, sal_Int32 nColumn ) const 1451 { 1452 ScCsvGrid& rGrid = implGetGrid(); 1453 sal_Int32 nLine = nRow + rGrid.GetFirstVisLine() - 1; 1454 String aCellStr; 1455 if( (nColumn > 0) && (nRow > 0) ) 1456 aCellStr = rGrid.GetCellText( lcl_GetGridColumn( nColumn ), nLine ); 1457 else if( nRow > 0 ) 1458 aCellStr = String::CreateFromInt32( nLine + 1L ); 1459 else if( nColumn > 0 ) 1460 aCellStr = rGrid.GetColumnTypeName( lcl_GetGridColumn( nColumn ) ); 1461 return aCellStr; 1462 } 1463 1464 1465 ScAccessibleCsvControl* ScAccessibleCsvGrid::implCreateCellObj( sal_Int32 nRow, sal_Int32 nColumn ) const 1466 { 1467 return new ScAccessibleCsvCell( implGetGrid(), implGetCellText( nRow, nColumn ), nRow, nColumn ); 1468 } 1469 1470 1471 // ============================================================================ 1472 1473 DBG_NAME( ScAccessibleCsvCell ) 1474 1475 ScAccessibleCsvCell::ScAccessibleCsvCell( 1476 ScCsvGrid& rGrid, 1477 const String& rCellText, 1478 sal_Int32 nRow, sal_Int32 nColumn ) : 1479 ScAccessibleCsvControl( rGrid.GetAccessible(), rGrid, nCellRole ), 1480 AccessibleStaticTextBase( SvxEditSourcePtr( NULL ) ), 1481 maCellText( rCellText ), 1482 mnLine( nRow ? (nRow + rGrid.GetFirstVisLine() - 1) : CSV_LINE_HEADER ), 1483 mnColumn( lcl_GetGridColumn( nColumn ) ), 1484 mnIndex( nRow * (rGrid.GetColumnCount() + 1) + nColumn ) 1485 { 1486 DBG_CTOR( ScAccessibleCsvCell, NULL ); 1487 SetEditSource( implCreateEditSource() ); 1488 } 1489 1490 ScAccessibleCsvCell::~ScAccessibleCsvCell() 1491 { 1492 DBG_DTOR( ScAccessibleCsvCell, NULL ); 1493 } 1494 1495 void SAL_CALL ScAccessibleCsvCell::disposing() 1496 { 1497 ScUnoGuard aGuard; 1498 SetEditSource( SvxEditSourcePtr( NULL ) ); 1499 ScAccessibleCsvControl::disposing(); 1500 } 1501 1502 1503 // XAccessibleComponent ------------------------------------------------------- 1504 1505 void SAL_CALL ScAccessibleCsvCell::grabFocus() throw( RuntimeException ) 1506 { 1507 ScUnoGuard aGuard; 1508 ensureAlive(); 1509 ScCsvGrid& rGrid = implGetGrid(); 1510 rGrid.Execute( CSVCMD_MOVEGRIDCURSOR, rGrid.GetColumnPos( mnColumn ) ); 1511 } 1512 1513 sal_Int32 SAL_CALL ScAccessibleCsvCell::getForeground( ) 1514 throw (RuntimeException) 1515 { 1516 ScUnoGuard aGuard; 1517 ensureAlive(); 1518 return implGetGrid().GetSettings().GetStyleSettings().GetButtonTextColor().GetColor(); 1519 } 1520 1521 sal_Int32 SAL_CALL ScAccessibleCsvCell::getBackground( ) 1522 throw (RuntimeException) 1523 { 1524 ScUnoGuard aGuard; 1525 ensureAlive(); 1526 return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor; 1527 } 1528 1529 // XAccessibleContext ----------------------------------------------------- 1530 1531 sal_Int32 SAL_CALL ScAccessibleCsvCell::getAccessibleChildCount() throw( RuntimeException ) 1532 { 1533 return AccessibleStaticTextBase::getAccessibleChildCount(); 1534 } 1535 1536 Reference< XAccessible > SAL_CALL ScAccessibleCsvCell::getAccessibleChild( sal_Int32 nIndex ) 1537 throw( IndexOutOfBoundsException, RuntimeException ) 1538 { 1539 return AccessibleStaticTextBase::getAccessibleChild( nIndex ); 1540 } 1541 1542 sal_Int32 SAL_CALL ScAccessibleCsvCell::getAccessibleIndexInParent() throw( RuntimeException ) 1543 { 1544 ScUnoGuard aGuard; 1545 ensureAlive(); 1546 return mnIndex; 1547 } 1548 1549 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvCell::getAccessibleRelationSet() 1550 throw( RuntimeException ) 1551 { 1552 ScUnoGuard aGuard; 1553 ensureAlive(); 1554 return new AccessibleRelationSetHelper(); 1555 } 1556 1557 Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvCell::getAccessibleStateSet() 1558 throw( RuntimeException ) 1559 { 1560 ScUnoGuard aGuard; 1561 AccessibleStateSetHelper* pStateSet = implCreateStateSet(); 1562 if( implIsAlive() ) 1563 { 1564 const ScCsvGrid& rGrid = implGetGrid(); 1565 pStateSet->AddState( AccessibleStateType::SINGLE_LINE ); 1566 if( mnColumn != CSV_COLUMN_HEADER ) 1567 pStateSet->AddState( AccessibleStateType::SELECTABLE ); 1568 if( rGrid.HasFocus() && (rGrid.GetFocusColumn() == mnColumn) && (mnLine == CSV_LINE_HEADER) ) 1569 pStateSet->AddState( AccessibleStateType::ACTIVE ); 1570 if( rGrid.IsSelected( mnColumn ) ) 1571 pStateSet->AddState( AccessibleStateType::SELECTED ); 1572 } 1573 return pStateSet; 1574 } 1575 1576 // XInterface ----------------------------------------------------------------- 1577 1578 IMPLEMENT_FORWARD_XINTERFACE2( ScAccessibleCsvCell, ScAccessibleCsvControl, AccessibleStaticTextBase ) 1579 1580 // XTypeProvider -------------------------------------------------------------- 1581 1582 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScAccessibleCsvCell, ScAccessibleCsvControl, AccessibleStaticTextBase ) 1583 1584 // XServiceInfo --------------------------------------------------------------- 1585 1586 OUString SAL_CALL ScAccessibleCsvCell::getImplementationName() throw( RuntimeException ) 1587 { 1588 return CREATE_OUSTRING( CELL_IMPL_NAME ); 1589 } 1590 1591 // helpers -------------------------------------------------------------------- 1592 1593 Rectangle ScAccessibleCsvCell::GetBoundingBoxOnScreen() const throw( RuntimeException ) 1594 { 1595 ScUnoGuard aGuard; 1596 ensureAlive(); 1597 Rectangle aRect( implGetBoundingBox() ); 1598 aRect.SetPos( implGetAbsPos( aRect.TopLeft() ) ); 1599 return aRect; 1600 } 1601 1602 Rectangle ScAccessibleCsvCell::GetBoundingBox() const throw( RuntimeException ) 1603 { 1604 ScUnoGuard aGuard; 1605 ensureAlive(); 1606 return implGetBoundingBox(); 1607 } 1608 1609 OUString SAL_CALL ScAccessibleCsvCell::createAccessibleName() throw( RuntimeException ) 1610 { 1611 return maCellText; 1612 } 1613 1614 OUString SAL_CALL ScAccessibleCsvCell::createAccessibleDescription() throw( RuntimeException ) 1615 { 1616 return OUString(); 1617 } 1618 1619 ScCsvGrid& ScAccessibleCsvCell::implGetGrid() const 1620 { 1621 return static_cast< ScCsvGrid& >( implGetControl() ); 1622 } 1623 1624 Point ScAccessibleCsvCell::implGetRealPos() const 1625 { 1626 ScCsvGrid& rGrid = implGetGrid(); 1627 return Point( 1628 (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrX() : rGrid.GetColumnX( mnColumn ), 1629 (mnLine == CSV_LINE_HEADER) ? 0 : rGrid.GetY( mnLine ) ); 1630 } 1631 1632 sal_uInt32 ScAccessibleCsvCell::implCalcPixelWidth(sal_uInt32 nChars) const 1633 { 1634 ScCsvGrid& rGrid = implGetGrid(); 1635 return rGrid.GetCharWidth() * nChars; 1636 } 1637 1638 Size ScAccessibleCsvCell::implGetRealSize() const 1639 { 1640 ScCsvGrid& rGrid = implGetGrid(); 1641 return Size( 1642 (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrWidth() : implCalcPixelWidth( rGrid.GetColumnWidth( mnColumn ) ), 1643 (mnLine == CSV_LINE_HEADER) ? rGrid.GetHdrHeight() : rGrid.GetLineHeight() ); 1644 } 1645 1646 Rectangle ScAccessibleCsvCell::implGetBoundingBox() const 1647 { 1648 ScCsvGrid& rGrid = implGetGrid(); 1649 Rectangle aClipRect( Point( 0, 0 ), rGrid.GetSizePixel() ); 1650 if( mnColumn != CSV_COLUMN_HEADER ) 1651 { 1652 aClipRect.Left() = rGrid.GetFirstX(); 1653 aClipRect.Right() = rGrid.GetLastX(); 1654 } 1655 if( mnLine != CSV_LINE_HEADER ) 1656 aClipRect.Top() = rGrid.GetHdrHeight(); 1657 1658 Rectangle aRect( implGetRealPos(), implGetRealSize() ); 1659 aRect.Intersection( aClipRect ); 1660 if( (aRect.GetWidth() <= 0) || (aRect.GetHeight() <= 0) ) 1661 aRect.SetSize( Size( -1, -1 ) ); 1662 return aRect; 1663 } 1664 1665 ::std::auto_ptr< SvxEditSource > ScAccessibleCsvCell::implCreateEditSource() 1666 { 1667 ScCsvGrid& rGrid = implGetGrid(); 1668 Rectangle aBoundRect( implGetBoundingBox() ); 1669 aBoundRect -= implGetRealPos(); 1670 1671 ::std::auto_ptr< ScAccessibleTextData > pCsvTextData( new ScAccessibleCsvTextData( 1672 &rGrid, rGrid.GetEditEngine(), maCellText, aBoundRect, implGetRealSize() ) ); 1673 1674 ::std::auto_ptr< SvxEditSource > pEditSource( new ScAccessibilityEditSource( pCsvTextData ) ); 1675 return pEditSource; 1676 } 1677 1678 1679 // ============================================================================ 1680 1681