merge the formfield patch from ooo-build
[ooovba.git] / sc / source / ui / Accessibility / AccessibleCsvControl.cxx
blob5cd0b17b8c2453f997bfdfc081b19726bd644c74
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: AccessibleCsvControl.cxx,v $
10 * $Revision: 1.22.32.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 // ============================================================================
35 #include "AccessibleCsvControl.hxx"
36 #include <com/sun/star/accessibility/AccessibleRole.hpp>
37 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLERELATIONTYPE_HPP_
38 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
39 #endif
40 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
41 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
42 #endif
43 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
44 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
45 #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
46 #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
47 #include <tools/debug.hxx>
48 #include <rtl/uuid.h>
49 #include <toolkit/helper/convert.hxx>
50 #include <unotools/accessiblerelationsethelper.hxx>
51 #ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
52 #include <unotools/accessiblestatesethelper.hxx>
53 #endif
54 #include <comphelper/sequence.hxx>
55 #include "scitems.hxx"
56 #include <svx/fontitem.hxx>
57 #include <svx/fhgtitem.hxx>
58 #include <svx/langitem.hxx>
59 #include "csvcontrol.hxx"
60 #include "csvruler.hxx"
61 #include "csvgrid.hxx"
62 #include "AccessibleText.hxx"
63 #include "editsrc.hxx"
64 #include "unoguard.hxx"
65 #include "scresid.hxx"
66 #include "sc.hrc"
67 #include "scmod.hxx"
68 #include <svtools/colorcfg.hxx>
69 // ause
70 #include "editutil.hxx"
72 using ::rtl::OUString;
73 using ::rtl::OUStringBuffer;
74 using ::utl::AccessibleRelationSetHelper;
75 using ::utl::AccessibleStateSetHelper;
76 using ::accessibility::AccessibleStaticTextBase;
77 using ::com::sun::star::uno::Any;
78 using ::com::sun::star::uno::Reference;
79 using ::com::sun::star::uno::Sequence;
80 using ::com::sun::star::uno::RuntimeException;
81 using ::com::sun::star::uno::XInterface;
82 using ::com::sun::star::lang::DisposedException;
83 using ::com::sun::star::lang::IndexOutOfBoundsException;
84 using ::com::sun::star::lang::IllegalArgumentException;
85 using ::com::sun::star::beans::PropertyValue;
86 using namespace ::com::sun::star::accessibility;
89 // ----------------------------------------------------------------------------
91 const sal_uInt16 nRulerRole = AccessibleRole::TEXT;
92 const sal_uInt16 nGridRole = AccessibleRole::TABLE;
93 const sal_uInt16 nCellRole = AccessibleRole::TEXT;
95 #define CREATE_OUSTRING( name ) OUString( RTL_CONSTASCII_USTRINGPARAM( name ) )
97 #define RULER_IMPL_NAME "ScAccessibleCsvRuler"
98 #define GRID_IMPL_NAME "ScAccessibleCsvGrid"
99 #define CELL_IMPL_NAME "ScAccessibleCsvCell"
101 const sal_Unicode cRulerDot = '.';
102 const sal_Unicode cRulerLine = '|';
104 const sal_Int32 CSV_LINE_HEADER = CSV_POS_INVALID;
105 const sal_uInt32 CSV_COLUMN_HEADER = CSV_COLUMN_INVALID;
108 // CSV base control ===========================================================
110 DBG_NAME( ScAccessibleCsvControl )
112 ScAccessibleCsvControl::ScAccessibleCsvControl(
113 const Reference< XAccessible >& rxParent,
114 ScCsvControl& rControl,
115 sal_uInt16 nRole ) :
116 ScAccessibleContextBase( rxParent, nRole ),
117 mpControl( &rControl )
119 DBG_CTOR( ScAccessibleCsvControl, NULL );
122 ScAccessibleCsvControl::~ScAccessibleCsvControl()
124 DBG_DTOR( ScAccessibleCsvControl, NULL );
125 implDispose();
128 void SAL_CALL ScAccessibleCsvControl::disposing()
130 ScUnoGuard aGuard;
131 mpControl = NULL;
132 ScAccessibleContextBase::disposing();
136 // XAccessibleComponent -------------------------------------------------------
138 Reference< XAccessible > SAL_CALL ScAccessibleCsvControl::getAccessibleAtPoint( const AwtPoint& /* rPoint */ )
139 throw( RuntimeException )
141 ensureAlive();
142 return NULL;
145 sal_Bool SAL_CALL ScAccessibleCsvControl::isVisible() throw( RuntimeException )
147 ScUnoGuard aGuard;
148 ensureAlive();
149 return implGetControl().IsVisible();
152 void SAL_CALL ScAccessibleCsvControl::grabFocus() throw( RuntimeException )
154 ScUnoGuard aGuard;
155 ensureAlive();
156 implGetControl().GrabFocus();
160 // events ---------------------------------------------------------------------
162 void ScAccessibleCsvControl::SendFocusEvent( bool bFocused )
164 if( bFocused )
165 CommitFocusGained();
166 else
167 CommitFocusLost();
170 void ScAccessibleCsvControl::SendCaretEvent()
172 DBG_ERRORFILE( "ScAccessibleCsvControl::SendCaretEvent - Illegal call" );
175 void ScAccessibleCsvControl::SendVisibleEvent()
177 AccessibleEventObject aEvent;
178 aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
179 aEvent.Source = Reference< XAccessible >( this );
180 CommitChange( aEvent );
183 void ScAccessibleCsvControl::SendSelectionEvent()
185 AccessibleEventObject aEvent;
186 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
187 aEvent.Source = Reference< XAccessible >( this );
188 CommitChange( aEvent );
191 void ScAccessibleCsvControl::SendTableUpdateEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */, bool /* bAllRows */ )
193 DBG_ERRORFILE( "ScAccessibleCsvControl::SendTableUpdateEvent - Illegal call" );
196 void ScAccessibleCsvControl::SendInsertColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ )
198 DBG_ERRORFILE( "ScAccessibleCsvControl::SendInsertColumnEvent - Illegal call" );
201 void ScAccessibleCsvControl::SendRemoveColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ )
203 DBG_ERRORFILE( "ScAccessibleCsvControl::SendRemoveColumnEvent - Illegal call" );
207 // helpers --------------------------------------------------------------------
209 Rectangle ScAccessibleCsvControl::GetBoundingBoxOnScreen() const throw( RuntimeException )
211 ScUnoGuard aGuard;
212 ensureAlive();
213 return implGetControl().GetWindowExtentsRelative( NULL );
216 Rectangle ScAccessibleCsvControl::GetBoundingBox() const throw( RuntimeException )
218 ScUnoGuard aGuard;
219 ensureAlive();
220 return implGetControl().GetWindowExtentsRelative( implGetControl().GetAccessibleParentWindow() );
223 void ScAccessibleCsvControl::getUuid( Sequence< sal_Int8 >& rSeq )
225 ScUnoGuard aGuard;
226 ensureAlive();
227 if( !rSeq.hasElements() )
229 rSeq.realloc( 16 );
230 rtl_createUuid( reinterpret_cast< sal_uInt8* >( rSeq.getArray() ), NULL, sal_True );
234 void ScAccessibleCsvControl::ensureAlive() const throw( DisposedException )
236 if( !implIsAlive() )
237 throw DisposedException();
240 ScCsvControl& ScAccessibleCsvControl::implGetControl() const
242 DBG_ASSERT( mpControl, "ScAccessibleCsvControl::implGetControl - missing control" );
243 return *mpControl;
246 Reference< XAccessible > ScAccessibleCsvControl::implGetChildByRole(
247 const Reference< XAccessible >& rxParentObj, sal_uInt16 nRole ) throw( RuntimeException )
249 Reference< XAccessible > xAccObj;
250 if( rxParentObj.is() )
252 Reference< XAccessibleContext > xParentCtxt = rxParentObj->getAccessibleContext();
253 if( xParentCtxt.is() )
255 sal_Int32 nCount = xParentCtxt->getAccessibleChildCount();
256 sal_Int32 nIndex = 0;
257 while( !xAccObj.is() && (nIndex < nCount) )
259 Reference< XAccessible > xCurrObj = xParentCtxt->getAccessibleChild( nIndex );
260 if( xCurrObj.is() )
262 Reference< XAccessibleContext > xCurrCtxt = xCurrObj->getAccessibleContext();
263 if( xCurrCtxt.is() && (xCurrCtxt->getAccessibleRole() == nRole) )
264 xAccObj = xCurrObj;
266 ++nIndex;
270 return xAccObj;
273 AccessibleStateSetHelper* ScAccessibleCsvControl::implCreateStateSet()
275 ScUnoGuard aGuard;
276 AccessibleStateSetHelper* pStateSet = new AccessibleStateSetHelper();
277 if( implIsAlive() )
279 const ScCsvControl& rCtrl = implGetControl();
280 pStateSet->AddState( AccessibleStateType::OPAQUE );
281 if( rCtrl.IsEnabled() )
282 pStateSet->AddState( AccessibleStateType::ENABLED );
283 if( isShowing() )
284 pStateSet->AddState( AccessibleStateType::SHOWING );
285 if( isVisible() )
286 pStateSet->AddState( AccessibleStateType::VISIBLE );
288 else
289 pStateSet->AddState( AccessibleStateType::DEFUNC );
290 return pStateSet;
293 void ScAccessibleCsvControl::implDispose()
295 if( implIsAlive() )
297 // prevent multiple call of dtor
298 osl_incrementInterlockedCount( &m_refCount );
299 dispose();
303 Point ScAccessibleCsvControl::implGetAbsPos( const Point& rPos ) const
305 return rPos + implGetControl().GetWindowExtentsRelative( NULL ).TopLeft();
309 // Ruler ======================================================================
311 /** Converts a ruler cursor position to API text index. */
312 sal_Int32 lcl_GetApiPos( sal_Int32 nRulerPos )
314 sal_Int32 nApiPos = nRulerPos;
315 sal_Int32 nStart = (nRulerPos - 1) / 10;
316 sal_Int32 nExp = 1;
317 while( nStart >= nExp )
319 nApiPos += nStart - nExp + 1;
320 nExp *= 10;
322 return ::std::max( nApiPos, static_cast<sal_Int32>(0) );
325 /** Converts an API text index to a ruler cursor position. */
326 sal_Int32 lcl_GetRulerPos( sal_Int32 nApiPos )
328 sal_Int32 nDiv = 10;
329 sal_Int32 nExp = 10;
330 sal_Int32 nRulerPos = 0;
331 sal_Int32 nApiBase = 0;
332 sal_Int32 nApiLimit = 10;
333 while( nApiPos >= nApiLimit )
335 ++nDiv;
336 nRulerPos = nExp;
337 nExp *= 10;
338 nApiBase = nApiLimit;
339 nApiLimit = lcl_GetApiPos( nExp );
341 sal_Int32 nRelPos = nApiPos - nApiBase;
342 return nRulerPos + nRelPos / nDiv * 10 + ::std::max( nRelPos % nDiv - nDiv + 10L, 0L );
345 /** Expands the sequence's size and returns the base index of the new inserted elements. */
346 inline sal_Int32 lcl_ExpandSequence( Sequence< PropertyValue >& rSeq, sal_Int32 nExp )
348 DBG_ASSERT( nExp > 0, "lcl_ExpandSequence - invalid value" );
349 rSeq.realloc( rSeq.getLength() + nExp );
350 return rSeq.getLength() - nExp;
353 /** Fills the property value rVal with the specified name and value from the item. */
354 inline void lcl_FillProperty( PropertyValue& rVal, const OUString& rPropName, const SfxPoolItem& rItem, sal_uInt8 nMID )
356 rVal.Name = rPropName;
357 rItem.QueryValue( rVal.Value, nMID );
360 /** Fills the sequence with all font attributes of rFont. */
361 void lcl_FillFontAttributes( Sequence< PropertyValue >& rSeq, const Font& rFont )
363 SvxFontItem aFontItem( rFont.GetFamily(), rFont.GetName(), rFont.GetStyleName(), rFont.GetPitch(), rFont.GetCharSet(), ATTR_FONT );
364 SvxFontHeightItem aHeightItem( rFont.GetSize().Height(), 100, ATTR_FONT_HEIGHT );
365 SvxLanguageItem aLangItem( rFont.GetLanguage(), ATTR_FONT_LANGUAGE );
367 sal_Int32 nIndex = lcl_ExpandSequence( rSeq, 7 );
368 lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontName" ), aFontItem, MID_FONT_FAMILY_NAME );
369 lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontFamily" ), aFontItem, MID_FONT_FAMILY );
370 lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontStyleName" ), aFontItem, MID_FONT_STYLE_NAME );
371 lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontCharSet" ), aFontItem, MID_FONT_PITCH );
372 lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontPitch" ), aFontItem, MID_FONT_CHAR_SET );
373 lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharHeight" ), aHeightItem, MID_FONTHEIGHT );
374 lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharLocale" ), aLangItem, MID_LANG_LOCALE );
379 // ----------------------------------------------------------------------------
381 DBG_NAME( ScAccessibleCsvRuler )
383 ScAccessibleCsvRuler::ScAccessibleCsvRuler( ScCsvRuler& rRuler ) :
384 ScAccessibleCsvControl( rRuler.GetAccessibleParentWindow()->GetAccessible(), rRuler, nRulerRole )
386 DBG_CTOR( ScAccessibleCsvRuler, NULL );
387 constructStringBuffer();
390 ScAccessibleCsvRuler::~ScAccessibleCsvRuler()
392 DBG_DTOR( ScAccessibleCsvRuler, NULL );
393 implDispose();
396 // XAccessibleComponent -----------------------------------------------------
398 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getForeground( )
399 throw (RuntimeException)
401 ScUnoGuard aGuard;
402 ensureAlive();
403 return implGetRuler().GetSettings().GetStyleSettings().GetLabelTextColor().GetColor();
406 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getBackground( )
407 throw (RuntimeException)
409 ScUnoGuard aGuard;
410 ensureAlive();
411 return implGetRuler().GetSettings().GetStyleSettings().GetFaceColor().GetColor();
414 // XAccessibleContext ---------------------------------------------------------
416 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getAccessibleChildCount() throw( RuntimeException )
418 ensureAlive();
419 return 0;
422 Reference< XAccessible > SAL_CALL ScAccessibleCsvRuler::getAccessibleChild( sal_Int32 /* nIndex */ )
423 throw( IndexOutOfBoundsException, RuntimeException )
425 ensureAlive();
426 throw IndexOutOfBoundsException();
429 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvRuler::getAccessibleRelationSet()
430 throw( RuntimeException )
432 ScUnoGuard aGuard;
433 ensureAlive();
434 AccessibleRelationSetHelper* pRelationSet = new AccessibleRelationSetHelper();
435 Reference< XAccessible > xAccObj = implGetChildByRole( getAccessibleParent(), nGridRole );
436 if( xAccObj.is() )
438 Sequence< Reference< XInterface > > aSeq( 1 );
439 aSeq[ 0 ] = xAccObj;
440 pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::CONTROLLER_FOR, aSeq ) );
442 return pRelationSet;
445 Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvRuler::getAccessibleStateSet()
446 throw( RuntimeException )
448 ScUnoGuard aGuard;
449 AccessibleStateSetHelper* pStateSet = implCreateStateSet();
450 if( implIsAlive() )
452 pStateSet->AddState( AccessibleStateType::FOCUSABLE );
453 pStateSet->AddState( AccessibleStateType::SINGLE_LINE );
454 if( implGetRuler().HasFocus() )
455 pStateSet->AddState( AccessibleStateType::FOCUSED );
457 return pStateSet;
461 // XAccessibleText ------------------------------------------------------------
463 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCaretPosition() throw( RuntimeException )
465 ScUnoGuard aGuard;
466 ensureAlive();
467 return lcl_GetApiPos( implGetRuler().GetRulerCursorPos() );
470 sal_Bool SAL_CALL ScAccessibleCsvRuler::setCaretPosition( sal_Int32 nIndex )
471 throw( IndexOutOfBoundsException, RuntimeException )
473 ScUnoGuard aGuard;
474 ensureAlive();
475 ensureValidIndex( nIndex );
476 ScCsvRuler& rRuler = implGetRuler();
477 sal_Int32 nOldCursor = rRuler.GetRulerCursorPos();
478 rRuler.Execute( CSVCMD_MOVERULERCURSOR, lcl_GetRulerPos( nIndex ) );
479 return rRuler.GetRulerCursorPos() != nOldCursor;
482 sal_Unicode SAL_CALL ScAccessibleCsvRuler::getCharacter( sal_Int32 nIndex )
483 throw( IndexOutOfBoundsException, RuntimeException )
485 ScUnoGuard aGuard;
486 ensureAlive();
487 ensureValidIndex( nIndex );
488 return maBuffer.charAt( nIndex );
491 Sequence< PropertyValue > SAL_CALL ScAccessibleCsvRuler::getCharacterAttributes( sal_Int32 nIndex,
492 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& /* aRequestedAttributes */ )
493 throw( IndexOutOfBoundsException, RuntimeException )
495 ScUnoGuard aGuard;
496 ensureAlive();
497 ensureValidIndexWithEnd( nIndex );
498 Sequence< PropertyValue > aSeq;
499 lcl_FillFontAttributes( aSeq, implGetRuler().GetFont() );
500 //! TODO split attribute: waiting for #102221#
501 // if( implHasSplit( nIndex ) )
502 // {
503 // sal_Int32 nIndex = lcl_ExpandSequence( aSeq, 1 );
504 // aSeq[ nIndex ].Name = CREATE_OUSTRING( "..." );
505 // aSeq[ nIndex ].Value <<= ...;
506 // }
507 return aSeq;
510 ScAccessibleCsvRuler::AwtRectangle SAL_CALL ScAccessibleCsvRuler::getCharacterBounds( sal_Int32 nIndex )
511 throw( IndexOutOfBoundsException, RuntimeException )
513 ScUnoGuard aGuard;
514 ensureAlive();
515 ensureValidIndexWithEnd( nIndex );
516 ScCsvRuler& rRuler = implGetRuler();
517 Point aPos( rRuler.GetX( lcl_GetRulerPos( nIndex ) ) - rRuler.GetCharWidth() / 2, 0 );
518 AwtRectangle aRect( aPos.X(), aPos.Y(), rRuler.GetCharWidth(), rRuler.GetSizePixel().Height() );
519 // #107054# do not return rectangle out of window
520 sal_Int32 nWidth = rRuler.GetOutputSizePixel().Width();
521 if( aRect.X >= nWidth )
522 throw IndexOutOfBoundsException();
523 if( aRect.X + aRect.Width > nWidth )
524 aRect.Width = nWidth - aRect.X;
525 return aRect;
528 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCharacterCount() throw( RuntimeException )
530 ScUnoGuard aGuard;
531 ensureAlive();
532 return implGetTextLength();
535 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getIndexAtPoint( const AwtPoint& rPoint )
536 throw( RuntimeException )
538 ScUnoGuard aGuard;
539 ensureAlive();
540 ScCsvRuler& rRuler = implGetRuler();
541 // #107054# use object's coordinate system, convert to API position
542 return lcl_GetApiPos( ::std::min( ::std::max( rRuler.GetPosFromX( rPoint.X ), static_cast<sal_Int32>(0) ), rRuler.GetPosCount() ) );
545 OUString SAL_CALL ScAccessibleCsvRuler::getSelectedText() throw( RuntimeException )
547 ensureAlive();
548 return OUString();
551 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionStart() throw( RuntimeException )
553 ensureAlive();
554 return -1;
557 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionEnd() throw( RuntimeException )
559 ensureAlive();
560 return -1;
563 sal_Bool SAL_CALL ScAccessibleCsvRuler::setSelection( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ )
564 throw( IndexOutOfBoundsException, RuntimeException )
566 ensureAlive();
567 return sal_False;
570 OUString SAL_CALL ScAccessibleCsvRuler::getText() throw( RuntimeException )
572 ScUnoGuard aGuard;
573 ensureAlive();
574 return OUString( maBuffer.getStr(), implGetTextLength() );
577 OUString SAL_CALL ScAccessibleCsvRuler::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
578 throw( IndexOutOfBoundsException, RuntimeException )
580 ScUnoGuard aGuard;
581 ensureAlive();
582 ensureValidRange( nStartIndex, nEndIndex );
583 return OUString( maBuffer.getStr() + nStartIndex, nEndIndex - nStartIndex );
586 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextAtIndex( sal_Int32 nIndex, sal_Int16 nTextType )
587 throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException )
589 ScUnoGuard aGuard;
590 ensureAlive();
592 TextSegment aResult;
593 aResult.SegmentStart = -1;
594 aResult.SegmentEnd = -1;
596 if( (nIndex == implGetTextLength()) && (nTextType != AccessibleTextType::LINE) )
597 return aResult;
599 ensureValidIndex( nIndex );
601 OUStringBuffer aResultText; // will be assigned to aResult.SegmentText below
602 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
604 switch( nTextType )
606 // single character
607 case AccessibleTextType::CHARACTER:
609 aResult.SegmentStart = nIndex;
610 aResultText.append( maBuffer.charAt( nIndex ) );
612 break;
614 // entire number or single dot/line
615 case AccessibleTextType::WORD:
616 case AccessibleTextType::GLYPH:
617 aResult.SegmentStart = nIndex;
618 if( nRulerPos % 10 )
619 aResultText.append( maBuffer.charAt( nIndex ) );
620 else
621 aResultText.append( nRulerPos ); // string representation of sal_Int32!!!
622 break;
624 // entire text
625 case AccessibleTextType::SENTENCE:
626 case AccessibleTextType::PARAGRAPH:
627 case AccessibleTextType::LINE:
628 aResult.SegmentStart = 0;
629 aResultText.append( maBuffer.getStr(), implGetTextLength() );
630 break;
632 // equal-formatted text
633 case AccessibleTextType::ATTRIBUTE_RUN:
635 sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex );
636 sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex );
637 aResult.SegmentStart = nFirstIndex;
638 aResultText.append( maBuffer.getStr() + nFirstIndex, nLastIndex - nFirstIndex + 1 );
640 break;
642 default:
643 throw RuntimeException();
646 aResult.SegmentText = aResultText.makeStringAndClear();
647 aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
648 return aResult;
651 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 nTextType )
652 throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException )
654 ScUnoGuard aGuard;
655 ensureAlive();
656 ensureValidIndexWithEnd( nIndex );
658 TextSegment aResult;
659 aResult.SegmentStart = -1;
660 aResult.SegmentEnd = -1;
662 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
664 switch( nTextType )
666 // single character
667 case AccessibleTextType::CHARACTER:
668 if( nIndex > 0 )
669 aResult = getTextAtIndex( nIndex - 1, nTextType );
670 // else empty
671 break;
673 // entire number or single dot/line
674 case AccessibleTextType::WORD:
675 case AccessibleTextType::GLYPH:
676 if( nRulerPos > 0 )
677 aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos - 1 ), nTextType );
678 // else empty
679 break;
681 // entire text
682 case AccessibleTextType::SENTENCE:
683 case AccessibleTextType::PARAGRAPH:
684 case AccessibleTextType::LINE:
685 // empty
686 break;
688 // equal-formatted text
689 case AccessibleTextType::ATTRIBUTE_RUN:
691 sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex );
692 if( nFirstIndex > 0 )
693 aResult = getTextAtIndex( nFirstIndex - 1, nTextType );
694 // else empty
696 break;
698 default:
699 throw RuntimeException();
701 return aResult;
704 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 nTextType )
705 throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException )
707 ScUnoGuard aGuard;
708 ensureAlive();
709 ensureValidIndexWithEnd( nIndex );
711 TextSegment aResult;
712 aResult.SegmentStart = -1;
713 aResult.SegmentEnd = -1;
715 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
716 sal_Int32 nLastValid = implGetTextLength();
718 switch( nTextType )
720 // single character
721 case AccessibleTextType::CHARACTER:
722 if( nIndex < nLastValid )
723 aResult = getTextAtIndex( nIndex + 1, nTextType );
724 // else empty
725 break;
727 // entire number or single dot/line
728 case AccessibleTextType::WORD:
729 case AccessibleTextType::GLYPH:
730 if( nRulerPos < implGetRuler().GetPosCount() )
731 aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos + 1 ), nTextType );
732 // else empty
733 break;
735 // entire text
736 case AccessibleTextType::SENTENCE:
737 case AccessibleTextType::PARAGRAPH:
738 case AccessibleTextType::LINE:
739 // empty
740 break;
742 // equal-formatted text
743 case AccessibleTextType::ATTRIBUTE_RUN:
745 sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex );
746 if( nLastIndex < nLastValid )
747 aResult = getTextAtIndex( nLastIndex + 1, nTextType );
748 // else empty
750 break;
752 default:
753 throw RuntimeException();
755 return aResult;
758 sal_Bool SAL_CALL ScAccessibleCsvRuler::copyText( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ )
759 throw( IndexOutOfBoundsException, RuntimeException )
761 ensureAlive();
762 return sal_False;
766 // XInterface -----------------------------------------------------------------
768 Any SAL_CALL ScAccessibleCsvRuler::queryInterface( const ::com::sun::star::uno::Type& rType )
769 throw( RuntimeException )
771 Any aAny( ScAccessibleCsvRulerImpl::queryInterface( rType ) );
772 return aAny.hasValue() ? aAny : ScAccessibleCsvControl::queryInterface( rType );
775 void SAL_CALL ScAccessibleCsvRuler::acquire() throw ()
777 ScAccessibleCsvControl::acquire();
780 void SAL_CALL ScAccessibleCsvRuler::release() throw ()
782 ScAccessibleCsvControl::release();
786 // XServiceInfo ---------------------------------------------------------------
788 OUString SAL_CALL ScAccessibleCsvRuler::getImplementationName() throw( RuntimeException )
790 return CREATE_OUSTRING( RULER_IMPL_NAME );
794 // XTypeProvider --------------------------------------------------------------
796 Sequence< ::com::sun::star::uno::Type > SAL_CALL ScAccessibleCsvRuler::getTypes() throw( RuntimeException )
798 Sequence< ::com::sun::star::uno::Type > aSeq( 1 );
799 aSeq[ 0 ] = getCppuType( static_cast< const Reference< XAccessibleText >* >( NULL ) );
800 return ::comphelper::concatSequences( ScAccessibleCsvControl::getTypes(), aSeq );
803 Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvRuler::getImplementationId() throw( RuntimeException )
805 static Sequence< sal_Int8 > aSeq;
806 getUuid( aSeq );
807 return aSeq;
811 // events ---------------------------------------------------------------------
813 void ScAccessibleCsvRuler::SendCaretEvent()
815 sal_Int32 nPos = implGetRuler().GetRulerCursorPos();
816 if( nPos != CSV_POS_INVALID )
818 AccessibleEventObject aEvent;
819 aEvent.EventId = AccessibleEventId::CARET_CHANGED;
820 aEvent.Source = Reference< XAccessible >( this );
821 aEvent.NewValue <<= nPos;
822 CommitChange( aEvent );
827 // helpers --------------------------------------------------------------------
829 OUString SAL_CALL ScAccessibleCsvRuler::createAccessibleName() throw( RuntimeException )
831 return String( ScResId( STR_ACC_CSVRULER_NAME ) );
834 OUString SAL_CALL ScAccessibleCsvRuler::createAccessibleDescription() throw( RuntimeException )
836 return String( ScResId( STR_ACC_CSVRULER_DESCR ) );
839 void ScAccessibleCsvRuler::ensureValidIndex( sal_Int32 nIndex ) const
840 throw( IndexOutOfBoundsException )
842 if( (nIndex < 0) || (nIndex >= implGetTextLength()) )
843 throw IndexOutOfBoundsException();
846 void ScAccessibleCsvRuler::ensureValidIndexWithEnd( sal_Int32 nIndex ) const
847 throw( IndexOutOfBoundsException )
849 if( (nIndex < 0) || (nIndex > implGetTextLength()) )
850 throw IndexOutOfBoundsException();
853 void ScAccessibleCsvRuler::ensureValidRange( sal_Int32& rnStartIndex, sal_Int32& rnEndIndex ) const
854 throw( IndexOutOfBoundsException )
856 if( rnStartIndex > rnEndIndex )
857 ::std::swap( rnStartIndex, rnEndIndex );
858 if( (rnStartIndex < 0) || (rnEndIndex > implGetTextLength()) )
859 throw IndexOutOfBoundsException();
862 ScCsvRuler& ScAccessibleCsvRuler::implGetRuler() const
864 return static_cast< ScCsvRuler& >( implGetControl() );
867 void ScAccessibleCsvRuler::constructStringBuffer() throw( RuntimeException )
869 ScUnoGuard aGuard;
870 ensureAlive();
871 // extend existing string buffer to new ruler size
872 sal_Int32 nRulerCount = implGetRuler().GetPosCount();
873 sal_Int32 nRulerPos = lcl_GetRulerPos( maBuffer.getLength() );
874 for( ; nRulerPos <= nRulerCount; ++nRulerPos ) // include last position
876 switch( nRulerPos % 10 )
878 case 0: maBuffer.append( nRulerPos ); break;
879 case 5: maBuffer.append( cRulerLine ); break;
880 default: maBuffer.append( cRulerDot );
885 sal_Int32 ScAccessibleCsvRuler::implGetTextLength() const
887 return lcl_GetApiPos( implGetRuler().GetPosCount() + 1 );
890 bool ScAccessibleCsvRuler::implHasSplit( sal_Int32 nApiPos )
892 sal_Int32 nRulerPos = lcl_GetRulerPos( nApiPos );
893 return implGetRuler().HasSplit( nRulerPos ) && (nApiPos == lcl_GetApiPos( nRulerPos ));
896 sal_Int32 ScAccessibleCsvRuler::implGetFirstEqualFormatted( sal_Int32 nApiPos )
898 bool bSplit = implHasSplit( nApiPos );
899 while( (nApiPos > 0) && (implHasSplit( nApiPos - 1 ) == bSplit) )
900 --nApiPos;
901 return nApiPos;
904 sal_Int32 ScAccessibleCsvRuler::implGetLastEqualFormatted( sal_Int32 nApiPos )
906 bool bSplit = implHasSplit( nApiPos );
907 sal_Int32 nLength = implGetTextLength();
908 while( (nApiPos < nLength - 1) && (implHasSplit( nApiPos + 1 ) == bSplit) )
909 ++nApiPos;
910 return nApiPos;
914 // Grid =======================================================================
916 /** Converts a grid columnm index to an API column index. */
917 inline sal_Int32 lcl_GetApiColumn( sal_uInt32 nGridColumn )
919 return (nGridColumn != CSV_COLUMN_HEADER) ? static_cast< sal_Int32 >( nGridColumn + 1 ) : 0;
922 /** Converts an API columnm index to a ScCsvGrid column index. */
923 inline sal_uInt32 lcl_GetGridColumn( sal_Int32 nApiColumn )
925 return (nApiColumn > 0) ? static_cast< sal_uInt32 >( nApiColumn - 1 ) : CSV_COLUMN_HEADER;
929 // ----------------------------------------------------------------------------
931 DBG_NAME( ScAccessibleCsvGrid )
933 ScAccessibleCsvGrid::ScAccessibleCsvGrid( ScCsvGrid& rGrid ) :
934 ScAccessibleCsvControl( rGrid.GetAccessibleParentWindow()->GetAccessible(), rGrid, nGridRole )
936 DBG_CTOR( ScAccessibleCsvGrid, NULL );
939 ScAccessibleCsvGrid::~ScAccessibleCsvGrid()
941 DBG_DTOR( ScAccessibleCsvGrid, NULL );
942 implDispose();
946 // XAccessibleComponent -------------------------------------------------------
948 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleAtPoint( const AwtPoint& rPoint )
949 throw( RuntimeException )
951 Reference< XAccessible > xRet;
952 if( containsPoint( rPoint ) )
954 ScUnoGuard aGuard;
955 ensureAlive();
957 const ScCsvGrid& rGrid = implGetGrid();
958 // #102679#; use <= instead of <, because the offset is the size and not the point
959 sal_Int32 nColumn = ((rGrid.GetFirstX() <= rPoint.X) && (rPoint.X <= rGrid.GetLastX())) ?
960 lcl_GetApiColumn( rGrid.GetColumnFromX( rPoint.X ) ) : 0;
961 sal_Int32 nRow = (rPoint.Y >= rGrid.GetHdrHeight()) ?
962 (rGrid.GetLineFromY( rPoint.Y ) - rGrid.GetFirstVisLine() + 1) : 0;
963 xRet = implCreateCellObj( nRow, nColumn );
965 return xRet;
968 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getForeground( )
969 throw (RuntimeException)
971 ScUnoGuard aGuard;
972 ensureAlive();
973 return implGetGrid().GetSettings().GetStyleSettings().GetButtonTextColor().GetColor();
976 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getBackground( )
977 throw (RuntimeException)
979 ScUnoGuard aGuard;
980 ensureAlive();
981 return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
984 // XAccessibleContext ---------------------------------------------------------
986 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleChildCount() throw( RuntimeException )
988 ScUnoGuard aGuard;
989 ensureAlive();
990 return implGetCellCount();
993 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleChild( sal_Int32 nIndex )
994 throw( IndexOutOfBoundsException, RuntimeException )
996 ScUnoGuard aGuard;
997 ensureAlive();
998 ensureValidIndex( nIndex );
999 return implCreateCellObj( implGetRow( nIndex ), implGetColumn( nIndex ) );
1002 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleRelationSet()
1003 throw( RuntimeException )
1005 ScUnoGuard aGuard;
1006 ensureAlive();
1007 AccessibleRelationSetHelper* pRelationSet = new AccessibleRelationSetHelper();
1008 Reference< XAccessible > xAccObj = implGetChildByRole( getAccessibleParent(), nRulerRole );
1009 if( xAccObj.is() )
1011 Sequence< Reference< XInterface > > aSeq( 1 );
1012 aSeq[ 0 ] = xAccObj;
1013 pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::CONTROLLED_BY, aSeq ) );
1015 return pRelationSet;
1018 Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleStateSet()
1019 throw( RuntimeException )
1021 ScUnoGuard aGuard;
1022 AccessibleStateSetHelper* pStateSet = implCreateStateSet();
1023 if( implIsAlive() )
1025 pStateSet->AddState( AccessibleStateType::FOCUSABLE );
1026 pStateSet->AddState( AccessibleStateType::MULTI_SELECTABLE );
1027 pStateSet->AddState( AccessibleStateType::MANAGES_DESCENDANTS );
1028 if( implGetGrid().HasFocus() )
1029 pStateSet->AddState( AccessibleStateType::FOCUSED );
1031 else
1032 pStateSet->AddState( AccessibleStateType::DEFUNC );
1033 return pStateSet;
1037 // XAccessibleTable -----------------------------------------------------------
1039 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowCount() throw( RuntimeException )
1041 ScUnoGuard aGuard;
1042 ensureAlive();
1043 return implGetRowCount();
1046 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnCount() throw( RuntimeException )
1048 ScUnoGuard aGuard;
1049 ensureAlive();
1050 return implGetColumnCount();
1053 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleRowDescription( sal_Int32 nRow )
1054 throw( IndexOutOfBoundsException, RuntimeException )
1056 ScUnoGuard aGuard;
1057 ensureAlive();
1058 ensureValidPosition( nRow, 0 );
1059 return implGetCellText( nRow, 0 );
1062 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnDescription( sal_Int32 nColumn )
1063 throw( IndexOutOfBoundsException, RuntimeException )
1065 ScUnoGuard aGuard;
1066 ensureAlive();
1067 ensureValidPosition( 0, nColumn );
1068 return implGetCellText( 0, nColumn );
1071 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
1072 throw( IndexOutOfBoundsException, RuntimeException )
1074 ensureAlive();
1075 ensureValidPosition( nRow, nColumn );
1076 return 1;
1079 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
1080 throw( IndexOutOfBoundsException, RuntimeException )
1082 ensureAlive();
1083 ensureValidPosition( nRow, nColumn );
1084 return 1;
1087 Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleRowHeaders()
1088 throw( RuntimeException )
1090 ensureAlive();
1091 return NULL;
1094 Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnHeaders()
1095 throw( RuntimeException )
1097 ensureAlive();
1098 return NULL;
1101 Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleRows()
1102 throw( RuntimeException )
1104 ensureAlive();
1105 return Sequence< sal_Int32 >();
1108 Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleColumns()
1109 throw( RuntimeException )
1111 ScUnoGuard aGuard;
1112 ensureAlive();
1114 ScCsvGrid& rGrid = implGetGrid();
1115 Sequence< sal_Int32 > aSeq( implGetColumnCount() );
1117 sal_Int32 nSeqIx = 0;
1118 sal_uInt32 nColIx = rGrid.GetFirstSelected();
1119 for( ; nColIx != CSV_COLUMN_INVALID; ++nSeqIx, nColIx = rGrid.GetNextSelected( nColIx ) )
1120 aSeq[ nSeqIx ] = lcl_GetApiColumn( nColIx );
1122 aSeq.realloc( nSeqIx );
1123 return aSeq;
1126 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleRowSelected( sal_Int32 /* nRow */ )
1127 throw( IndexOutOfBoundsException, RuntimeException )
1129 ensureAlive();
1130 return sal_False;
1133 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleColumnSelected( sal_Int32 nColumn )
1134 throw( IndexOutOfBoundsException, RuntimeException )
1136 ScUnoGuard aGuard;
1137 ensureAlive();
1138 ensureValidIndex( nColumn );
1139 return implIsColumnSelected( nColumn );
1142 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
1143 throw( IndexOutOfBoundsException, RuntimeException )
1145 ScUnoGuard aGuard;
1146 ensureAlive();
1147 ensureValidPosition( nRow, nColumn );
1148 return implCreateCellObj( nRow, nColumn );
1151 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCaption()
1152 throw( RuntimeException )
1154 ensureAlive();
1155 return NULL;
1158 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleSummary()
1159 throw( RuntimeException )
1161 ensureAlive();
1162 return NULL;
1165 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 nColumn )
1166 throw( IndexOutOfBoundsException, RuntimeException )
1168 return isAccessibleColumnSelected( nColumn );
1171 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
1172 throw( IndexOutOfBoundsException, RuntimeException )
1174 ScUnoGuard aGuard;
1175 ensureAlive();
1176 ensureValidPosition( nRow, nColumn );
1177 return implGetIndex( nRow, nColumn );
1180 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRow( sal_Int32 nChildIndex )
1181 throw( IndexOutOfBoundsException, RuntimeException )
1183 ScUnoGuard aGuard;
1184 ensureAlive();
1185 ensureValidIndex( nChildIndex );
1186 return implGetRow( nChildIndex );
1189 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumn( sal_Int32 nChildIndex )
1190 throw( IndexOutOfBoundsException, RuntimeException )
1192 ScUnoGuard aGuard;
1193 ensureAlive();
1194 ensureValidIndex( nChildIndex );
1195 return implGetColumn( nChildIndex );
1199 // XAccessibleSelection -------------------------------------------------------
1201 void SAL_CALL ScAccessibleCsvGrid::selectAccessibleChild( sal_Int32 nChildIndex )
1202 throw( IndexOutOfBoundsException, RuntimeException )
1204 ScUnoGuard aGuard;
1205 ensureAlive();
1206 ensureValidIndex( nChildIndex );
1207 sal_Int32 nColumn = implGetColumn( nChildIndex );
1208 if( nChildIndex == 0 )
1209 implGetGrid().SelectAll();
1210 else
1211 implSelectColumn( nColumn, true );
1214 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleChildSelected( sal_Int32 nChildIndex )
1215 throw( IndexOutOfBoundsException, RuntimeException )
1217 ScUnoGuard aGuard;
1218 ensureAlive();
1219 ensureValidIndex( nChildIndex );
1220 sal_Int32 nColumn = implGetColumn( nChildIndex );
1221 return implIsColumnSelected( nColumn );
1224 void SAL_CALL ScAccessibleCsvGrid::clearAccessibleSelection() throw( RuntimeException )
1226 ScUnoGuard aGuard;
1227 ensureAlive();
1228 implGetGrid().SelectAll( false );
1231 void SAL_CALL ScAccessibleCsvGrid::selectAllAccessibleChildren() throw( RuntimeException )
1233 selectAccessibleChild( 0 );
1236 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChildCount() throw( RuntimeException )
1238 ScUnoGuard aGuard;
1239 ensureAlive();
1240 return implGetRowCount() * implGetSelColumnCount();
1243 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
1244 throw( IndexOutOfBoundsException, RuntimeException )
1246 ScUnoGuard aGuard;
1247 ensureAlive();
1248 sal_Int32 nColumns = implGetSelColumnCount();
1249 if( nColumns == 0 )
1250 throw IndexOutOfBoundsException();
1252 sal_Int32 nRow = nSelectedChildIndex / nColumns;
1253 sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns );
1254 return getAccessibleCellAt( nRow, nColumn );
1257 void SAL_CALL ScAccessibleCsvGrid::deselectAccessibleChild( sal_Int32 nSelectedChildIndex )
1258 throw( IndexOutOfBoundsException, RuntimeException )
1260 ScUnoGuard aGuard;
1261 ensureAlive();
1262 sal_Int32 nColumns = implGetSelColumnCount();
1263 if( nColumns == 0 )
1264 throw IndexOutOfBoundsException();
1266 sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns );
1267 ensureValidPosition( nSelectedChildIndex / nColumns, nColumn );
1268 if( nColumn > 0 )
1269 implSelectColumn( nColumn, false );
1273 // XInterface -----------------------------------------------------------------
1275 Any SAL_CALL ScAccessibleCsvGrid::queryInterface( const ::com::sun::star::uno::Type& rType )
1276 throw( RuntimeException )
1278 Any aAny( ScAccessibleCsvGridImpl::queryInterface( rType ) );
1279 return aAny.hasValue() ? aAny : ScAccessibleCsvControl::queryInterface( rType );
1282 void SAL_CALL ScAccessibleCsvGrid::acquire() throw ()
1284 ScAccessibleCsvControl::acquire();
1287 void SAL_CALL ScAccessibleCsvGrid::release() throw ()
1289 ScAccessibleCsvControl::release();
1293 // XServiceInfo ---------------------------------------------------------------
1295 OUString SAL_CALL ScAccessibleCsvGrid::getImplementationName() throw( RuntimeException )
1297 return CREATE_OUSTRING( GRID_IMPL_NAME );
1301 // XTypeProvider --------------------------------------------------------------
1303 Sequence< ::com::sun::star::uno::Type > SAL_CALL ScAccessibleCsvGrid::getTypes() throw( RuntimeException )
1305 Sequence< ::com::sun::star::uno::Type > aSeq( 2 );
1306 aSeq[ 0 ] = getCppuType( static_cast< const Reference< XAccessibleTable >* >( NULL ) );
1307 aSeq[ 1 ] = getCppuType( static_cast< const Reference< XAccessibleSelection >* >( NULL ) );
1308 return ::comphelper::concatSequences( ScAccessibleCsvControl::getTypes(), aSeq );
1311 Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvGrid::getImplementationId() throw( RuntimeException )
1313 static Sequence< sal_Int8 > aSeq;
1314 getUuid( aSeq );
1315 return aSeq;
1319 // events ---------------------------------------------------------------------
1321 void ScAccessibleCsvGrid::SendFocusEvent( bool bFocused )
1323 ScAccessibleCsvControl::SendFocusEvent( bFocused );
1325 AccessibleEventObject aEvent;
1326 aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
1327 aEvent.Source = Reference< XAccessible >( this );
1328 (bFocused ? aEvent.NewValue : aEvent.OldValue) <<=
1329 getAccessibleCellAt( 0, lcl_GetApiColumn( implGetGrid().GetFocusColumn() ) );
1330 CommitChange( aEvent );
1333 void ScAccessibleCsvGrid::SendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows )
1335 if( nFirstColumn <= nLastColumn )
1337 AccessibleTableModelChange aModelChange(
1338 AccessibleTableModelChangeType::UPDATE, 0, bAllRows ? implGetRowCount() - 1 : 0,
1339 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1340 AccessibleEventObject aEvent;
1341 aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
1342 aEvent.Source = Reference< XAccessible >( this );
1343 aEvent.NewValue <<= aModelChange;
1344 CommitChange( aEvent );
1348 void ScAccessibleCsvGrid::SendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
1350 if( nFirstColumn <= nLastColumn )
1352 AccessibleTableModelChange aModelChange(
1353 AccessibleTableModelChangeType::INSERT, 0, implGetRowCount() - 1,
1354 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1355 AccessibleEventObject aEvent;
1356 aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
1357 aEvent.Source = Reference< XAccessible >( this );
1358 aEvent.NewValue <<= aModelChange;
1359 CommitChange( aEvent );
1363 void ScAccessibleCsvGrid::SendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
1365 if( nFirstColumn <= nLastColumn )
1367 AccessibleTableModelChange aModelChange(
1368 AccessibleTableModelChangeType::DELETE, 0, implGetRowCount() - 1,
1369 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1370 AccessibleEventObject aEvent;
1371 aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
1372 aEvent.Source = Reference< XAccessible >( this );
1373 aEvent.NewValue <<= aModelChange;
1374 CommitChange( aEvent );
1379 // helpers --------------------------------------------------------------------
1381 OUString SAL_CALL ScAccessibleCsvGrid::createAccessibleName() throw( RuntimeException )
1383 return String( ScResId( STR_ACC_CSVGRID_NAME ) );
1386 OUString SAL_CALL ScAccessibleCsvGrid::createAccessibleDescription() throw( RuntimeException )
1388 return String( ScResId( STR_ACC_CSVGRID_DESCR ) );
1391 void ScAccessibleCsvGrid::ensureValidIndex( sal_Int32 nIndex ) const
1392 throw( IndexOutOfBoundsException )
1394 if( (nIndex < 0) || (nIndex >= implGetCellCount()) )
1395 throw IndexOutOfBoundsException();
1398 void ScAccessibleCsvGrid::ensureValidPosition( sal_Int32 nRow, sal_Int32 nColumn ) const
1399 throw( IndexOutOfBoundsException )
1401 if( (nRow < 0) || (nRow >= implGetRowCount()) || (nColumn < 0) || (nColumn >= implGetColumnCount()) )
1402 throw IndexOutOfBoundsException();
1405 ScCsvGrid& ScAccessibleCsvGrid::implGetGrid() const
1407 return static_cast< ScCsvGrid& >( implGetControl() );
1410 bool ScAccessibleCsvGrid::implIsColumnSelected( sal_Int32 nColumn ) const
1412 return (nColumn > 0) && implGetGrid().IsSelected( lcl_GetGridColumn( nColumn ) );
1415 void ScAccessibleCsvGrid::implSelectColumn( sal_Int32 nColumn, bool bSelect )
1417 if( nColumn > 0 )
1418 implGetGrid().Select( lcl_GetGridColumn( nColumn ), bSelect );
1421 sal_Int32 ScAccessibleCsvGrid::implGetRowCount() const
1423 return static_cast< sal_Int32 >( implGetGrid().GetLastVisLine() - implGetGrid().GetFirstVisLine() + 2 );
1426 sal_Int32 ScAccessibleCsvGrid::implGetColumnCount() const
1428 return static_cast< sal_Int32 >( implGetGrid().GetColumnCount() + 1 );
1431 sal_Int32 ScAccessibleCsvGrid::implGetSelColumnCount() const
1433 ScCsvGrid& rGrid = implGetGrid();
1434 sal_Int32 nCount = 0;
1435 for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) )
1436 ++nCount;
1437 return nCount;
1440 sal_Int32 ScAccessibleCsvGrid::implGetSelColumn( sal_Int32 nSelColumn ) const
1442 ScCsvGrid& rGrid = implGetGrid();
1443 sal_Int32 nColumn = 0;
1444 for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) )
1446 if( nColumn == nSelColumn )
1447 return static_cast< sal_Int32 >( nColIx + 1 );
1448 ++nColumn;
1450 return 0;
1453 String ScAccessibleCsvGrid::implGetCellText( sal_Int32 nRow, sal_Int32 nColumn ) const
1455 ScCsvGrid& rGrid = implGetGrid();
1456 sal_Int32 nLine = nRow + rGrid.GetFirstVisLine() - 1;
1457 String aCellStr;
1458 if( (nColumn > 0) && (nRow > 0) )
1459 aCellStr = rGrid.GetCellText( lcl_GetGridColumn( nColumn ), nLine );
1460 else if( nRow > 0 )
1461 aCellStr = String::CreateFromInt32( nLine + 1L );
1462 else if( nColumn > 0 )
1463 aCellStr = rGrid.GetColumnTypeName( lcl_GetGridColumn( nColumn ) );
1464 return aCellStr;
1468 ScAccessibleCsvControl* ScAccessibleCsvGrid::implCreateCellObj( sal_Int32 nRow, sal_Int32 nColumn ) const
1470 return new ScAccessibleCsvCell( implGetGrid(), implGetCellText( nRow, nColumn ), nRow, nColumn );
1474 // ============================================================================
1476 DBG_NAME( ScAccessibleCsvCell )
1478 ScAccessibleCsvCell::ScAccessibleCsvCell(
1479 ScCsvGrid& rGrid,
1480 const String& rCellText,
1481 sal_Int32 nRow, sal_Int32 nColumn ) :
1482 ScAccessibleCsvControl( rGrid.GetAccessible(), rGrid, nCellRole ),
1483 AccessibleStaticTextBase( SvxEditSourcePtr( NULL ) ),
1484 maCellText( rCellText ),
1485 mnLine( nRow ? (nRow + rGrid.GetFirstVisLine() - 1) : CSV_LINE_HEADER ),
1486 mnColumn( lcl_GetGridColumn( nColumn ) ),
1487 mnIndex( nRow * (rGrid.GetColumnCount() + 1) + nColumn )
1489 DBG_CTOR( ScAccessibleCsvCell, NULL );
1490 SetEditSource( implCreateEditSource() );
1493 ScAccessibleCsvCell::~ScAccessibleCsvCell()
1495 DBG_DTOR( ScAccessibleCsvCell, NULL );
1498 void SAL_CALL ScAccessibleCsvCell::disposing()
1500 ScUnoGuard aGuard;
1501 SetEditSource( SvxEditSourcePtr( NULL ) );
1502 ScAccessibleCsvControl::disposing();
1506 // XAccessibleComponent -------------------------------------------------------
1508 void SAL_CALL ScAccessibleCsvCell::grabFocus() throw( RuntimeException )
1510 ScUnoGuard aGuard;
1511 ensureAlive();
1512 ScCsvGrid& rGrid = implGetGrid();
1513 rGrid.Execute( CSVCMD_MOVEGRIDCURSOR, rGrid.GetColumnPos( mnColumn ) );
1516 sal_Int32 SAL_CALL ScAccessibleCsvCell::getForeground( )
1517 throw (RuntimeException)
1519 ScUnoGuard aGuard;
1520 ensureAlive();
1521 return implGetGrid().GetSettings().GetStyleSettings().GetButtonTextColor().GetColor();
1524 sal_Int32 SAL_CALL ScAccessibleCsvCell::getBackground( )
1525 throw (RuntimeException)
1527 ScUnoGuard aGuard;
1528 ensureAlive();
1529 return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
1532 // XAccessibleContext -----------------------------------------------------
1534 sal_Int32 SAL_CALL ScAccessibleCsvCell::getAccessibleChildCount() throw( RuntimeException )
1536 return AccessibleStaticTextBase::getAccessibleChildCount();
1539 Reference< XAccessible > SAL_CALL ScAccessibleCsvCell::getAccessibleChild( sal_Int32 nIndex )
1540 throw( IndexOutOfBoundsException, RuntimeException )
1542 return AccessibleStaticTextBase::getAccessibleChild( nIndex );
1545 sal_Int32 SAL_CALL ScAccessibleCsvCell::getAccessibleIndexInParent() throw( RuntimeException )
1547 ScUnoGuard aGuard;
1548 ensureAlive();
1549 return mnIndex;
1552 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvCell::getAccessibleRelationSet()
1553 throw( RuntimeException )
1555 ScUnoGuard aGuard;
1556 ensureAlive();
1557 return new AccessibleRelationSetHelper();
1560 Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvCell::getAccessibleStateSet()
1561 throw( RuntimeException )
1563 ScUnoGuard aGuard;
1564 AccessibleStateSetHelper* pStateSet = implCreateStateSet();
1565 if( implIsAlive() )
1567 const ScCsvGrid& rGrid = implGetGrid();
1568 pStateSet->AddState( AccessibleStateType::SINGLE_LINE );
1569 if( mnColumn != CSV_COLUMN_HEADER )
1570 pStateSet->AddState( AccessibleStateType::SELECTABLE );
1571 if( rGrid.HasFocus() && (rGrid.GetFocusColumn() == mnColumn) && (mnLine == CSV_LINE_HEADER) )
1572 pStateSet->AddState( AccessibleStateType::ACTIVE );
1573 if( rGrid.IsSelected( mnColumn ) )
1574 pStateSet->AddState( AccessibleStateType::SELECTED );
1576 return pStateSet;
1579 // XInterface -----------------------------------------------------------------
1581 IMPLEMENT_FORWARD_XINTERFACE2( ScAccessibleCsvCell, ScAccessibleCsvControl, AccessibleStaticTextBase )
1583 // XTypeProvider --------------------------------------------------------------
1585 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScAccessibleCsvCell, ScAccessibleCsvControl, AccessibleStaticTextBase )
1587 // XServiceInfo ---------------------------------------------------------------
1589 OUString SAL_CALL ScAccessibleCsvCell::getImplementationName() throw( RuntimeException )
1591 return CREATE_OUSTRING( CELL_IMPL_NAME );
1594 // helpers --------------------------------------------------------------------
1596 Rectangle ScAccessibleCsvCell::GetBoundingBoxOnScreen() const throw( RuntimeException )
1598 ScUnoGuard aGuard;
1599 ensureAlive();
1600 Rectangle aRect( implGetBoundingBox() );
1601 aRect.SetPos( implGetAbsPos( aRect.TopLeft() ) );
1602 return aRect;
1605 Rectangle ScAccessibleCsvCell::GetBoundingBox() const throw( RuntimeException )
1607 ScUnoGuard aGuard;
1608 ensureAlive();
1609 return implGetBoundingBox();
1612 OUString SAL_CALL ScAccessibleCsvCell::createAccessibleName() throw( RuntimeException )
1614 return maCellText;
1617 OUString SAL_CALL ScAccessibleCsvCell::createAccessibleDescription() throw( RuntimeException )
1619 return OUString();
1622 ScCsvGrid& ScAccessibleCsvCell::implGetGrid() const
1624 return static_cast< ScCsvGrid& >( implGetControl() );
1627 Point ScAccessibleCsvCell::implGetRealPos() const
1629 ScCsvGrid& rGrid = implGetGrid();
1630 return Point(
1631 (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrX() : rGrid.GetColumnX( mnColumn ),
1632 (mnLine == CSV_LINE_HEADER) ? 0 : rGrid.GetY( mnLine ) );
1635 sal_uInt32 ScAccessibleCsvCell::implCalcPixelWidth(sal_uInt32 nChars) const
1637 ScCsvGrid& rGrid = implGetGrid();
1638 return rGrid.GetCharWidth() * nChars;
1641 Size ScAccessibleCsvCell::implGetRealSize() const
1643 ScCsvGrid& rGrid = implGetGrid();
1644 return Size(
1645 (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrWidth() : implCalcPixelWidth( rGrid.GetColumnWidth( mnColumn ) ),
1646 (mnLine == CSV_LINE_HEADER) ? rGrid.GetHdrHeight() : rGrid.GetLineHeight() );
1649 Rectangle ScAccessibleCsvCell::implGetBoundingBox() const
1651 ScCsvGrid& rGrid = implGetGrid();
1652 Rectangle aClipRect( Point( 0, 0 ), rGrid.GetSizePixel() );
1653 if( mnColumn != CSV_COLUMN_HEADER )
1655 aClipRect.Left() = rGrid.GetFirstX();
1656 aClipRect.Right() = rGrid.GetLastX();
1658 if( mnLine != CSV_LINE_HEADER )
1659 aClipRect.Top() = rGrid.GetHdrHeight();
1661 Rectangle aRect( implGetRealPos(), implGetRealSize() );
1662 aRect.Intersection( aClipRect );
1663 if( (aRect.GetWidth() <= 0) || (aRect.GetHeight() <= 0) )
1664 aRect.SetSize( Size( -1, -1 ) );
1665 return aRect;
1668 ::std::auto_ptr< SvxEditSource > ScAccessibleCsvCell::implCreateEditSource()
1670 ScCsvGrid& rGrid = implGetGrid();
1671 Rectangle aBoundRect( implGetBoundingBox() );
1672 aBoundRect -= implGetRealPos();
1674 ::std::auto_ptr< ScAccessibleTextData > pCsvTextData( new ScAccessibleCsvTextData(
1675 &rGrid, rGrid.GetEditEngine(), maCellText, aBoundRect, implGetRealSize() ) );
1677 ::std::auto_ptr< SvxEditSource > pEditSource( new ScAccessibilityEditSource( pCsvTextData ) );
1678 return pEditSource;
1682 // ============================================================================