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