fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / Accessibility / AccessibleCsvControl.cxx
blobbb924f2befaf4357fb20e48b941c6bb5233eedc8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <utility>
24 #include "AccessibleCsvControl.hxx"
25 #include <com/sun/star/accessibility/AccessibleRole.hpp>
26 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
27 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
28 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
29 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
30 #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
31 #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
32 #include <tools/debug.hxx>
33 #include <toolkit/helper/convert.hxx>
34 #include <unotools/accessiblerelationsethelper.hxx>
35 #include <unotools/accessiblestatesethelper.hxx>
36 #include <comphelper/sequence.hxx>
37 #include <comphelper/servicehelper.hxx>
38 #include "scitems.hxx"
39 #include <editeng/fontitem.hxx>
40 #include <editeng/fhgtitem.hxx>
41 #include <editeng/langitem.hxx>
42 #include "csvcontrol.hxx"
43 #include "csvruler.hxx"
44 #include "csvgrid.hxx"
45 #include "AccessibleText.hxx"
46 #include "editsrc.hxx"
47 #include "scresid.hxx"
48 #include "sc.hrc"
49 #include "scmod.hxx"
50 #include <svtools/colorcfg.hxx>
51 #include <vcl/svapp.hxx>
52 #include <vcl/settings.hxx>
53 #include "editutil.hxx"
55 using ::utl::AccessibleRelationSetHelper;
56 using ::utl::AccessibleStateSetHelper;
57 using ::accessibility::AccessibleStaticTextBase;
58 using ::com::sun::star::uno::Any;
59 using ::com::sun::star::uno::Reference;
60 using ::com::sun::star::uno::Sequence;
61 using ::com::sun::star::uno::RuntimeException;
62 using ::com::sun::star::uno::XInterface;
63 using ::com::sun::star::lang::DisposedException;
64 using ::com::sun::star::lang::IndexOutOfBoundsException;
65 using ::com::sun::star::lang::IllegalArgumentException;
66 using ::com::sun::star::beans::PropertyValue;
67 using namespace ::com::sun::star::accessibility;
69 const sal_uInt16 nRulerRole = AccessibleRole::TEXT;
70 const sal_uInt16 nGridRole = AccessibleRole::TABLE;
71 const sal_uInt16 nCellRole = AccessibleRole::TEXT;
73 #define RULER_IMPL_NAME "ScAccessibleCsvRuler"
74 #define GRID_IMPL_NAME "ScAccessibleCsvGrid"
75 #define CELL_IMPL_NAME "ScAccessibleCsvCell"
77 const sal_Unicode cRulerDot = '.';
78 const sal_Unicode cRulerLine = '|';
80 const sal_Int32 CSV_LINE_HEADER = CSV_POS_INVALID;
81 const sal_uInt32 CSV_COLUMN_HEADER = CSV_COLUMN_INVALID;
83 ScAccessibleCsvControl::ScAccessibleCsvControl(
84 const Reference< XAccessible >& rxParent,
85 ScCsvControl& rControl,
86 sal_uInt16 nRole ) :
87 ScAccessibleContextBase( rxParent, nRole ),
88 mpControl( &rControl )
92 ScAccessibleCsvControl::~ScAccessibleCsvControl()
94 implDispose();
97 void SAL_CALL ScAccessibleCsvControl::disposing()
99 SolarMutexGuard aGuard;
100 mpControl = NULL;
101 ScAccessibleContextBase::disposing();
104 // XAccessibleComponent -------------------------------------------------------
106 Reference< XAccessible > SAL_CALL ScAccessibleCsvControl::getAccessibleAtPoint( const AwtPoint& /* rPoint */ )
107 throw( RuntimeException, std::exception )
109 ensureAlive();
110 return NULL;
113 bool SAL_CALL ScAccessibleCsvControl::isVisible() throw( RuntimeException, std::exception )
115 SolarMutexGuard aGuard;
116 ensureAlive();
117 return implGetControl().IsVisible();
120 void SAL_CALL ScAccessibleCsvControl::grabFocus() throw( RuntimeException, std::exception )
122 SolarMutexGuard aGuard;
123 ensureAlive();
124 implGetControl().GrabFocus();
127 // events ---------------------------------------------------------------------
129 void ScAccessibleCsvControl::SendFocusEvent( bool bFocused )
131 if( bFocused )
132 CommitFocusGained();
133 else
134 CommitFocusLost();
137 void ScAccessibleCsvControl::SendCaretEvent()
139 OSL_FAIL( "ScAccessibleCsvControl::SendCaretEvent - Illegal call" );
142 void ScAccessibleCsvControl::SendVisibleEvent()
144 AccessibleEventObject aEvent;
145 aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
146 aEvent.Source = Reference< XAccessible >( this );
147 CommitChange( aEvent );
150 void ScAccessibleCsvControl::SendSelectionEvent()
152 AccessibleEventObject aEvent;
153 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
154 aEvent.Source = Reference< XAccessible >( this );
155 CommitChange( aEvent );
158 void ScAccessibleCsvControl::SendTableUpdateEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */, bool /* bAllRows */ )
160 OSL_FAIL( "ScAccessibleCsvControl::SendTableUpdateEvent - Illegal call" );
163 void ScAccessibleCsvControl::SendInsertColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ )
165 OSL_FAIL( "ScAccessibleCsvControl::SendInsertColumnEvent - Illegal call" );
168 void ScAccessibleCsvControl::SendRemoveColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ )
170 OSL_FAIL( "ScAccessibleCsvControl::SendRemoveColumnEvent - Illegal call" );
173 // helpers --------------------------------------------------------------------
175 Rectangle ScAccessibleCsvControl::GetBoundingBoxOnScreen() const throw( RuntimeException, std::exception )
177 SolarMutexGuard aGuard;
178 ensureAlive();
179 return implGetControl().GetWindowExtentsRelative( NULL );
182 Rectangle ScAccessibleCsvControl::GetBoundingBox() const throw( RuntimeException, std::exception )
184 SolarMutexGuard aGuard;
185 ensureAlive();
186 return implGetControl().GetWindowExtentsRelative( implGetControl().GetAccessibleParentWindow() );
189 void ScAccessibleCsvControl::ensureAlive() const throw( DisposedException )
191 if( !implIsAlive() )
192 throw DisposedException();
195 ScCsvControl& ScAccessibleCsvControl::implGetControl() const
197 assert(mpControl && "ScAccessibleCsvControl::implGetControl - missing control");
198 return *mpControl;
201 Reference< XAccessible > ScAccessibleCsvControl::implGetChildByRole(
202 const Reference< XAccessible >& rxParentObj, sal_uInt16 nRole ) throw( RuntimeException )
204 Reference< XAccessible > xAccObj;
205 if( rxParentObj.is() )
207 Reference< XAccessibleContext > xParentCtxt = rxParentObj->getAccessibleContext();
208 if( xParentCtxt.is() )
210 sal_Int32 nCount = xParentCtxt->getAccessibleChildCount();
211 sal_Int32 nIndex = 0;
212 while( !xAccObj.is() && (nIndex < nCount) )
214 Reference< XAccessible > xCurrObj = xParentCtxt->getAccessibleChild( nIndex );
215 if( xCurrObj.is() )
217 Reference< XAccessibleContext > xCurrCtxt = xCurrObj->getAccessibleContext();
218 if( xCurrCtxt.is() && (xCurrCtxt->getAccessibleRole() == nRole) )
219 xAccObj = xCurrObj;
221 ++nIndex;
225 return xAccObj;
228 AccessibleStateSetHelper* ScAccessibleCsvControl::implCreateStateSet()
230 SolarMutexGuard aGuard;
231 AccessibleStateSetHelper* pStateSet = new AccessibleStateSetHelper();
232 if( implIsAlive() )
234 const ScCsvControl& rCtrl = implGetControl();
235 pStateSet->AddState( AccessibleStateType::OPAQUE );
236 if( rCtrl.IsEnabled() )
237 pStateSet->AddState( AccessibleStateType::ENABLED );
238 if( isShowing() )
239 pStateSet->AddState( AccessibleStateType::SHOWING );
240 if( isVisible() )
241 pStateSet->AddState( AccessibleStateType::VISIBLE );
243 else
244 pStateSet->AddState( AccessibleStateType::DEFUNC );
245 return pStateSet;
248 void ScAccessibleCsvControl::implDispose()
250 if( implIsAlive() )
252 // prevent multiple call of dtor
253 osl_atomic_increment( &m_refCount );
254 dispose();
258 Point ScAccessibleCsvControl::implGetAbsPos( const Point& rPos ) const
260 return rPos + implGetControl().GetWindowExtentsRelative( NULL ).TopLeft();
263 // Ruler ======================================================================
265 /** Converts a ruler cursor position to API text index. */
266 static sal_Int32 lcl_GetApiPos( sal_Int32 nRulerPos )
268 sal_Int32 nApiPos = nRulerPos;
269 sal_Int32 nStart = (nRulerPos - 1) / 10;
270 sal_Int32 nExp = 1;
271 while( nStart >= nExp )
273 nApiPos += nStart - nExp + 1;
274 nExp *= 10;
276 return ::std::max( nApiPos, static_cast<sal_Int32>(0) );
279 /** Converts an API text index to a ruler cursor position. */
280 static sal_Int32 lcl_GetRulerPos( sal_Int32 nApiPos )
282 sal_Int32 nDiv = 10;
283 sal_Int32 nExp = 10;
284 sal_Int32 nRulerPos = 0;
285 sal_Int32 nApiBase = 0;
286 sal_Int32 nApiLimit = 10;
287 while( nApiPos >= nApiLimit )
289 ++nDiv;
290 nRulerPos = nExp;
291 nExp *= 10;
292 nApiBase = nApiLimit;
293 nApiLimit = lcl_GetApiPos( nExp );
295 sal_Int32 nRelPos = nApiPos - nApiBase;
296 return nRulerPos + nRelPos / nDiv * 10 + ::std::max( nRelPos % nDiv - nDiv + 10L, 0L );
299 /** Expands the sequence's size and returns the base index of the new inserted elements. */
300 static inline sal_Int32 lcl_ExpandSequence( Sequence< PropertyValue >& rSeq, sal_Int32 nExp )
302 OSL_ENSURE( nExp > 0, "lcl_ExpandSequence - invalid value" );
303 rSeq.realloc( rSeq.getLength() + nExp );
304 return rSeq.getLength() - nExp;
307 /** Fills the property value rVal with the specified name and value from the item. */
308 static inline void lcl_FillProperty( PropertyValue& rVal, const OUString& rPropName, const SfxPoolItem& rItem, sal_uInt8 nMID )
310 rVal.Name = rPropName;
311 rItem.QueryValue( rVal.Value, nMID );
314 /** Fills the sequence with all font attributes of rFont. */
315 static void lcl_FillFontAttributes( Sequence< PropertyValue >& rSeq, const vcl::Font& rFont )
317 SvxFontItem aFontItem( rFont.GetFamily(), rFont.GetName(), rFont.GetStyleName(), rFont.GetPitch(), rFont.GetCharSet(), ATTR_FONT );
318 SvxFontHeightItem aHeightItem( rFont.GetSize().Height(), 100, ATTR_FONT_HEIGHT );
319 SvxLanguageItem aLangItem( rFont.GetLanguage(), ATTR_FONT_LANGUAGE );
321 sal_Int32 nIndex = lcl_ExpandSequence( rSeq, 7 );
322 lcl_FillProperty( rSeq[ nIndex++ ], "CharFontName", aFontItem, MID_FONT_FAMILY_NAME );
323 lcl_FillProperty( rSeq[ nIndex++ ], "CharFontFamily", aFontItem, MID_FONT_FAMILY );
324 lcl_FillProperty( rSeq[ nIndex++ ], "CharFontStyleName", aFontItem, MID_FONT_STYLE_NAME );
325 lcl_FillProperty( rSeq[ nIndex++ ], "CharFontCharSet", aFontItem, MID_FONT_PITCH );
326 lcl_FillProperty( rSeq[ nIndex++ ], "CharFontPitch", aFontItem, MID_FONT_CHAR_SET );
327 lcl_FillProperty( rSeq[ nIndex++ ], "CharHeight", aHeightItem, MID_FONTHEIGHT );
328 lcl_FillProperty( rSeq[ nIndex++ ], "CharLocale", aLangItem, MID_LANG_LOCALE );
331 ScAccessibleCsvRuler::ScAccessibleCsvRuler( ScCsvRuler& rRuler ) :
332 ScAccessibleCsvControl( rRuler.GetAccessibleParentWindow()->GetAccessible(), rRuler, nRulerRole )
334 constructStringBuffer();
337 ScAccessibleCsvRuler::~ScAccessibleCsvRuler()
339 implDispose();
342 // XAccessibleComponent -----------------------------------------------------
344 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getForeground( )
345 throw (RuntimeException, std::exception)
347 SolarMutexGuard aGuard;
348 ensureAlive();
349 return implGetRuler().GetSettings().GetStyleSettings().GetLabelTextColor().GetColor();
352 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getBackground( )
353 throw (RuntimeException, std::exception)
355 SolarMutexGuard aGuard;
356 ensureAlive();
357 return implGetRuler().GetSettings().GetStyleSettings().GetFaceColor().GetColor();
360 // XAccessibleContext ---------------------------------------------------------
362 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getAccessibleChildCount() throw( RuntimeException, std::exception )
364 ensureAlive();
365 return 0;
368 Reference< XAccessible > SAL_CALL ScAccessibleCsvRuler::getAccessibleChild( sal_Int32 /* nIndex */ )
369 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
371 ensureAlive();
372 throw IndexOutOfBoundsException();
375 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvRuler::getAccessibleRelationSet()
376 throw( RuntimeException, std::exception )
378 SolarMutexGuard aGuard;
379 ensureAlive();
380 AccessibleRelationSetHelper* pRelationSet = new AccessibleRelationSetHelper();
381 Reference< XAccessible > xAccObj = implGetChildByRole( getAccessibleParent(), nGridRole );
382 if( xAccObj.is() )
384 Sequence< Reference< XInterface > > aSeq( 1 );
385 aSeq[ 0 ] = xAccObj;
386 pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::CONTROLLER_FOR, aSeq ) );
388 return pRelationSet;
391 Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvRuler::getAccessibleStateSet()
392 throw( RuntimeException, std::exception )
394 SolarMutexGuard aGuard;
395 AccessibleStateSetHelper* pStateSet = implCreateStateSet();
396 if( implIsAlive() )
398 pStateSet->AddState( AccessibleStateType::FOCUSABLE );
399 pStateSet->AddState( AccessibleStateType::SINGLE_LINE );
400 if( implGetRuler().HasFocus() )
401 pStateSet->AddState( AccessibleStateType::FOCUSED );
403 return pStateSet;
406 // XAccessibleText ------------------------------------------------------------
408 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCaretPosition() throw( RuntimeException, std::exception )
410 SolarMutexGuard aGuard;
411 ensureAlive();
412 return lcl_GetApiPos( implGetRuler().GetRulerCursorPos() );
415 sal_Bool SAL_CALL ScAccessibleCsvRuler::setCaretPosition( sal_Int32 nIndex )
416 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
418 SolarMutexGuard aGuard;
419 ensureAlive();
420 ensureValidIndex( nIndex );
421 ScCsvRuler& rRuler = implGetRuler();
422 sal_Int32 nOldCursor = rRuler.GetRulerCursorPos();
423 rRuler.Execute( CSVCMD_MOVERULERCURSOR, lcl_GetRulerPos( nIndex ) );
424 return rRuler.GetRulerCursorPos() != nOldCursor;
427 sal_Unicode SAL_CALL ScAccessibleCsvRuler::getCharacter( sal_Int32 nIndex )
428 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
430 SolarMutexGuard aGuard;
431 ensureAlive();
432 ensureValidIndex( nIndex );
433 return maBuffer[nIndex];
436 Sequence< PropertyValue > SAL_CALL ScAccessibleCsvRuler::getCharacterAttributes( sal_Int32 nIndex,
437 const ::com::sun::star::uno::Sequence< OUString >& /* aRequestedAttributes */ )
438 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
440 SolarMutexGuard aGuard;
441 ensureAlive();
442 ensureValidIndexWithEnd( nIndex );
443 Sequence< PropertyValue > aSeq;
444 lcl_FillFontAttributes( aSeq, implGetRuler().GetFont() );
445 return aSeq;
448 ScAccessibleCsvRuler::AwtRectangle SAL_CALL ScAccessibleCsvRuler::getCharacterBounds( sal_Int32 nIndex )
449 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
451 SolarMutexGuard aGuard;
452 ensureAlive();
453 ensureValidIndexWithEnd( nIndex );
454 ScCsvRuler& rRuler = implGetRuler();
455 Point aPos( rRuler.GetX( lcl_GetRulerPos( nIndex ) ) - rRuler.GetCharWidth() / 2, 0 );
456 AwtRectangle aRect( aPos.X(), aPos.Y(), rRuler.GetCharWidth(), rRuler.GetSizePixel().Height() );
457 // do not return rectangle out of window
458 sal_Int32 nWidth = rRuler.GetOutputSizePixel().Width();
459 if( aRect.X >= nWidth )
460 throw IndexOutOfBoundsException();
461 if( aRect.X + aRect.Width > nWidth )
462 aRect.Width = nWidth - aRect.X;
463 return aRect;
466 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCharacterCount() throw( RuntimeException, std::exception )
468 SolarMutexGuard aGuard;
469 ensureAlive();
470 return implGetTextLength();
473 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getIndexAtPoint( const AwtPoint& rPoint )
474 throw( RuntimeException, std::exception )
476 SolarMutexGuard aGuard;
477 ensureAlive();
478 ScCsvRuler& rRuler = implGetRuler();
479 // use object's coordinate system, convert to API position
480 return lcl_GetApiPos( ::std::min( ::std::max( rRuler.GetPosFromX( rPoint.X ), static_cast<sal_Int32>(0) ), rRuler.GetPosCount() ) );
483 OUString SAL_CALL ScAccessibleCsvRuler::getSelectedText() throw( RuntimeException, std::exception )
485 ensureAlive();
486 return OUString();
489 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionStart() throw( RuntimeException, std::exception )
491 ensureAlive();
492 return -1;
495 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionEnd() throw( RuntimeException, std::exception )
497 ensureAlive();
498 return -1;
501 sal_Bool SAL_CALL ScAccessibleCsvRuler::setSelection( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ )
502 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
504 ensureAlive();
505 return false;
508 OUString SAL_CALL ScAccessibleCsvRuler::getText() throw( RuntimeException, std::exception )
510 SolarMutexGuard aGuard;
511 ensureAlive();
512 return OUString( maBuffer.getStr(), implGetTextLength() );
515 OUString SAL_CALL ScAccessibleCsvRuler::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
516 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
518 SolarMutexGuard aGuard;
519 ensureAlive();
520 ensureValidRange( nStartIndex, nEndIndex );
521 return OUString( maBuffer.getStr() + nStartIndex, nEndIndex - nStartIndex );
524 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextAtIndex( sal_Int32 nIndex, sal_Int16 nTextType )
525 throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException, std::exception )
527 SolarMutexGuard aGuard;
528 ensureAlive();
530 TextSegment aResult;
531 aResult.SegmentStart = -1;
532 aResult.SegmentEnd = -1;
534 if( (nIndex == implGetTextLength()) && (nTextType != AccessibleTextType::LINE) )
535 return aResult;
537 ensureValidIndex( nIndex );
539 OUStringBuffer aResultText; // will be assigned to aResult.SegmentText below
540 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
542 switch( nTextType )
544 // single character
545 case AccessibleTextType::CHARACTER:
547 aResult.SegmentStart = nIndex;
548 aResultText.append(maBuffer[nIndex]);
550 break;
552 // entire number or single dot/line
553 case AccessibleTextType::WORD:
554 case AccessibleTextType::GLYPH:
555 aResult.SegmentStart = nIndex;
556 if( nRulerPos % 10 )
557 aResultText.append(maBuffer[nIndex]);
558 else
559 aResultText.append( nRulerPos ); // string representation of sal_Int32!!!
560 break;
562 // entire text
563 case AccessibleTextType::SENTENCE:
564 case AccessibleTextType::PARAGRAPH:
565 case AccessibleTextType::LINE:
566 aResult.SegmentStart = 0;
567 aResultText.append( maBuffer.getStr(), implGetTextLength() );
568 break;
570 // equal-formatted text
571 case AccessibleTextType::ATTRIBUTE_RUN:
573 sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex );
574 sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex );
575 aResult.SegmentStart = nFirstIndex;
576 aResultText.append( maBuffer.getStr() + nFirstIndex, nLastIndex - nFirstIndex + 1 );
578 break;
580 default:
581 throw RuntimeException();
584 aResult.SegmentText = aResultText.makeStringAndClear();
585 aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
586 return aResult;
589 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 nTextType )
590 throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException, std::exception )
592 SolarMutexGuard aGuard;
593 ensureAlive();
594 ensureValidIndexWithEnd( nIndex );
596 TextSegment aResult;
597 aResult.SegmentStart = -1;
598 aResult.SegmentEnd = -1;
600 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
602 switch( nTextType )
604 // single character
605 case AccessibleTextType::CHARACTER:
606 if( nIndex > 0 )
607 aResult = getTextAtIndex( nIndex - 1, nTextType );
608 // else empty
609 break;
611 // entire number or single dot/line
612 case AccessibleTextType::WORD:
613 case AccessibleTextType::GLYPH:
614 if( nRulerPos > 0 )
615 aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos - 1 ), nTextType );
616 // else empty
617 break;
619 // entire text
620 case AccessibleTextType::SENTENCE:
621 case AccessibleTextType::PARAGRAPH:
622 case AccessibleTextType::LINE:
623 // empty
624 break;
626 // equal-formatted text
627 case AccessibleTextType::ATTRIBUTE_RUN:
629 sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex );
630 if( nFirstIndex > 0 )
631 aResult = getTextAtIndex( nFirstIndex - 1, nTextType );
632 // else empty
634 break;
636 default:
637 throw RuntimeException();
639 return aResult;
642 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 nTextType )
643 throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException, std::exception )
645 SolarMutexGuard aGuard;
646 ensureAlive();
647 ensureValidIndexWithEnd( nIndex );
649 TextSegment aResult;
650 aResult.SegmentStart = -1;
651 aResult.SegmentEnd = -1;
653 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
654 sal_Int32 nLastValid = implGetTextLength();
656 switch( nTextType )
658 // single character
659 case AccessibleTextType::CHARACTER:
660 if( nIndex < nLastValid )
661 aResult = getTextAtIndex( nIndex + 1, nTextType );
662 // else empty
663 break;
665 // entire number or single dot/line
666 case AccessibleTextType::WORD:
667 case AccessibleTextType::GLYPH:
668 if( nRulerPos < implGetRuler().GetPosCount() )
669 aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos + 1 ), nTextType );
670 // else empty
671 break;
673 // entire text
674 case AccessibleTextType::SENTENCE:
675 case AccessibleTextType::PARAGRAPH:
676 case AccessibleTextType::LINE:
677 // empty
678 break;
680 // equal-formatted text
681 case AccessibleTextType::ATTRIBUTE_RUN:
683 sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex );
684 if( nLastIndex < nLastValid )
685 aResult = getTextAtIndex( nLastIndex + 1, nTextType );
686 // else empty
688 break;
690 default:
691 throw RuntimeException();
693 return aResult;
696 sal_Bool SAL_CALL ScAccessibleCsvRuler::copyText( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ )
697 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
699 ensureAlive();
700 return false;
703 // XInterface -----------------------------------------------------------------
705 Any SAL_CALL ScAccessibleCsvRuler::queryInterface( const ::com::sun::star::uno::Type& rType )
706 throw( RuntimeException, std::exception )
708 Any aAny( ScAccessibleCsvRulerImpl::queryInterface( rType ) );
709 return aAny.hasValue() ? aAny : ScAccessibleCsvControl::queryInterface( rType );
712 void SAL_CALL ScAccessibleCsvRuler::acquire() throw ()
714 ScAccessibleCsvControl::acquire();
717 void SAL_CALL ScAccessibleCsvRuler::release() throw ()
719 ScAccessibleCsvControl::release();
722 // XServiceInfo ---------------------------------------------------------------
724 OUString SAL_CALL ScAccessibleCsvRuler::getImplementationName() throw( RuntimeException, std::exception )
726 return OUString( RULER_IMPL_NAME );
729 // XTypeProvider --------------------------------------------------------------
731 Sequence< ::com::sun::star::uno::Type > SAL_CALL ScAccessibleCsvRuler::getTypes() throw( RuntimeException, std::exception )
733 Sequence< ::com::sun::star::uno::Type > aSeq( 1 );
734 aSeq[ 0 ] = cppu::UnoType<XAccessibleText>::get();
735 return ::comphelper::concatSequences( ScAccessibleCsvControl::getTypes(), aSeq );
738 Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvRuler::getImplementationId() throw( RuntimeException, std::exception )
740 return css::uno::Sequence<sal_Int8>();
743 // events ---------------------------------------------------------------------
745 void ScAccessibleCsvRuler::SendCaretEvent()
747 sal_Int32 nPos = implGetRuler().GetRulerCursorPos();
748 if( nPos != CSV_POS_INVALID )
750 AccessibleEventObject aEvent;
751 aEvent.EventId = AccessibleEventId::CARET_CHANGED;
752 aEvent.Source = Reference< XAccessible >( this );
753 aEvent.NewValue <<= nPos;
754 CommitChange( aEvent );
758 // helpers --------------------------------------------------------------------
760 OUString SAL_CALL ScAccessibleCsvRuler::createAccessibleName() throw( RuntimeException, std::exception )
762 return OUString( ScResId( STR_ACC_CSVRULER_NAME ) );
765 OUString SAL_CALL ScAccessibleCsvRuler::createAccessibleDescription() throw( RuntimeException )
767 return OUString( ScResId( STR_ACC_CSVRULER_DESCR ) );
770 void ScAccessibleCsvRuler::ensureValidIndex( sal_Int32 nIndex ) const
771 throw( IndexOutOfBoundsException )
773 if( (nIndex < 0) || (nIndex >= implGetTextLength()) )
774 throw IndexOutOfBoundsException();
777 void ScAccessibleCsvRuler::ensureValidIndexWithEnd( sal_Int32 nIndex ) const
778 throw( IndexOutOfBoundsException )
780 if( (nIndex < 0) || (nIndex > implGetTextLength()) )
781 throw IndexOutOfBoundsException();
784 void ScAccessibleCsvRuler::ensureValidRange( sal_Int32& rnStartIndex, sal_Int32& rnEndIndex ) const
785 throw( IndexOutOfBoundsException )
787 if( rnStartIndex > rnEndIndex )
788 ::std::swap( rnStartIndex, rnEndIndex );
789 if( (rnStartIndex < 0) || (rnEndIndex > implGetTextLength()) )
790 throw IndexOutOfBoundsException();
793 ScCsvRuler& ScAccessibleCsvRuler::implGetRuler() const
795 return static_cast< ScCsvRuler& >( implGetControl() );
798 void ScAccessibleCsvRuler::constructStringBuffer() throw( RuntimeException )
800 SolarMutexGuard aGuard;
801 ensureAlive();
802 // extend existing string buffer to new ruler size
803 sal_Int32 nRulerCount = implGetRuler().GetPosCount();
804 sal_Int32 nRulerPos = lcl_GetRulerPos( maBuffer.getLength() );
805 for( ; nRulerPos <= nRulerCount; ++nRulerPos ) // include last position
807 switch( nRulerPos % 10 )
809 case 0: maBuffer.append( nRulerPos ); break;
810 case 5: maBuffer.append( cRulerLine ); break;
811 default: maBuffer.append( cRulerDot );
816 sal_Int32 ScAccessibleCsvRuler::implGetTextLength() const
818 return lcl_GetApiPos( implGetRuler().GetPosCount() + 1 );
821 bool ScAccessibleCsvRuler::implHasSplit( sal_Int32 nApiPos )
823 sal_Int32 nRulerPos = lcl_GetRulerPos( nApiPos );
824 return implGetRuler().HasSplit( nRulerPos ) && (nApiPos == lcl_GetApiPos( nRulerPos ));
827 sal_Int32 ScAccessibleCsvRuler::implGetFirstEqualFormatted( sal_Int32 nApiPos )
829 bool bSplit = implHasSplit( nApiPos );
830 while( (nApiPos > 0) && (implHasSplit( nApiPos - 1 ) == bSplit) )
831 --nApiPos;
832 return nApiPos;
835 sal_Int32 ScAccessibleCsvRuler::implGetLastEqualFormatted( sal_Int32 nApiPos )
837 bool bSplit = implHasSplit( nApiPos );
838 sal_Int32 nLength = implGetTextLength();
839 while( (nApiPos < nLength - 1) && (implHasSplit( nApiPos + 1 ) == bSplit) )
840 ++nApiPos;
841 return nApiPos;
844 // Grid =======================================================================
846 /** Converts a grid columnm index to an API column index. */
847 static inline sal_Int32 lcl_GetApiColumn( sal_uInt32 nGridColumn )
849 return (nGridColumn != CSV_COLUMN_HEADER) ? static_cast< sal_Int32 >( nGridColumn + 1 ) : 0;
852 /** Converts an API columnm index to a ScCsvGrid column index. */
853 static inline sal_uInt32 lcl_GetGridColumn( sal_Int32 nApiColumn )
855 return (nApiColumn > 0) ? static_cast< sal_uInt32 >( nApiColumn - 1 ) : CSV_COLUMN_HEADER;
858 ScAccessibleCsvGrid::ScAccessibleCsvGrid( ScCsvGrid& rGrid ) :
859 ScAccessibleCsvControl( rGrid.GetAccessibleParentWindow()->GetAccessible(), rGrid, nGridRole )
863 ScAccessibleCsvGrid::~ScAccessibleCsvGrid()
865 implDispose();
868 // XAccessibleComponent -------------------------------------------------------
870 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleAtPoint( const AwtPoint& rPoint )
871 throw( RuntimeException, std::exception )
873 Reference< XAccessible > xRet;
874 if( containsPoint( rPoint ) )
876 SolarMutexGuard aGuard;
877 ensureAlive();
879 const ScCsvGrid& rGrid = implGetGrid();
880 // #102679#; use <= instead of <, because the offset is the size and not the point
881 sal_Int32 nColumn = ((rGrid.GetFirstX() <= rPoint.X) && (rPoint.X <= rGrid.GetLastX())) ?
882 lcl_GetApiColumn( rGrid.GetColumnFromX( rPoint.X ) ) : 0;
883 sal_Int32 nRow = (rPoint.Y >= rGrid.GetHdrHeight()) ?
884 (rGrid.GetLineFromY( rPoint.Y ) - rGrid.GetFirstVisLine() + 1) : 0;
885 xRet = implCreateCellObj( nRow, nColumn );
887 return xRet;
890 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getForeground( )
891 throw (RuntimeException, std::exception)
893 SolarMutexGuard aGuard;
894 ensureAlive();
895 return implGetGrid().GetSettings().GetStyleSettings().GetButtonTextColor().GetColor();
898 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getBackground( )
899 throw (RuntimeException, std::exception)
901 SolarMutexGuard aGuard;
902 ensureAlive();
903 return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
906 // XAccessibleContext ---------------------------------------------------------
908 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleChildCount() throw( RuntimeException, std::exception )
910 SolarMutexGuard aGuard;
911 ensureAlive();
912 return implGetCellCount();
915 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleChild( sal_Int32 nIndex )
916 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
918 SolarMutexGuard aGuard;
919 ensureAlive();
920 ensureValidIndex( nIndex );
921 return implCreateCellObj( implGetRow( nIndex ), implGetColumn( nIndex ) );
924 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleRelationSet()
925 throw( RuntimeException, std::exception )
927 SolarMutexGuard aGuard;
928 ensureAlive();
929 AccessibleRelationSetHelper* pRelationSet = new AccessibleRelationSetHelper();
930 Reference< XAccessible > xAccObj = implGetChildByRole( getAccessibleParent(), nRulerRole );
931 if( xAccObj.is() )
933 Sequence< Reference< XInterface > > aSeq( 1 );
934 aSeq[ 0 ] = xAccObj;
935 pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::CONTROLLED_BY, aSeq ) );
937 return pRelationSet;
940 Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleStateSet()
941 throw( RuntimeException, std::exception )
943 SolarMutexGuard aGuard;
944 AccessibleStateSetHelper* pStateSet = implCreateStateSet();
945 if( implIsAlive() )
947 pStateSet->AddState( AccessibleStateType::FOCUSABLE );
948 pStateSet->AddState( AccessibleStateType::MULTI_SELECTABLE );
949 pStateSet->AddState( AccessibleStateType::MANAGES_DESCENDANTS );
950 if( implGetGrid().HasFocus() )
951 pStateSet->AddState( AccessibleStateType::FOCUSED );
953 else
954 pStateSet->AddState( AccessibleStateType::DEFUNC );
955 return pStateSet;
958 // XAccessibleTable -----------------------------------------------------------
960 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowCount() throw( RuntimeException, std::exception )
962 SolarMutexGuard aGuard;
963 ensureAlive();
964 return implGetRowCount();
967 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnCount() throw( RuntimeException, std::exception )
969 SolarMutexGuard aGuard;
970 ensureAlive();
971 return implGetColumnCount();
974 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleRowDescription( sal_Int32 nRow )
975 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
977 SolarMutexGuard aGuard;
978 ensureAlive();
979 ensureValidPosition( nRow, 0 );
980 return implGetCellText( nRow, 0 );
983 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnDescription( sal_Int32 nColumn )
984 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
986 SolarMutexGuard aGuard;
987 ensureAlive();
988 ensureValidPosition( 0, nColumn );
989 return implGetCellText( 0, nColumn );
992 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
993 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
995 ensureAlive();
996 ensureValidPosition( nRow, nColumn );
997 return 1;
1000 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
1001 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
1003 ensureAlive();
1004 ensureValidPosition( nRow, nColumn );
1005 return 1;
1008 Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleRowHeaders()
1009 throw( RuntimeException, std::exception )
1011 ensureAlive();
1012 return NULL;
1015 Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnHeaders()
1016 throw( RuntimeException, std::exception )
1018 ensureAlive();
1019 return NULL;
1022 Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleRows()
1023 throw( RuntimeException, std::exception )
1025 ensureAlive();
1026 return Sequence< sal_Int32 >();
1029 Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleColumns()
1030 throw( RuntimeException, std::exception )
1032 SolarMutexGuard aGuard;
1033 ensureAlive();
1035 ScCsvGrid& rGrid = implGetGrid();
1036 Sequence< sal_Int32 > aSeq( implGetColumnCount() );
1038 sal_Int32 nSeqIx = 0;
1039 sal_uInt32 nColIx = rGrid.GetFirstSelected();
1040 for( ; nColIx != CSV_COLUMN_INVALID; ++nSeqIx, nColIx = rGrid.GetNextSelected( nColIx ) )
1041 aSeq[ nSeqIx ] = lcl_GetApiColumn( nColIx );
1043 aSeq.realloc( nSeqIx );
1044 return aSeq;
1047 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleRowSelected( sal_Int32 /* nRow */ )
1048 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
1050 ensureAlive();
1051 return false;
1054 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleColumnSelected( sal_Int32 nColumn )
1055 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
1057 SolarMutexGuard aGuard;
1058 ensureAlive();
1059 ensureValidIndex( nColumn );
1060 return implIsColumnSelected( nColumn );
1063 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
1064 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
1066 SolarMutexGuard aGuard;
1067 ensureAlive();
1068 ensureValidPosition( nRow, nColumn );
1069 return implCreateCellObj( nRow, nColumn );
1072 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCaption()
1073 throw( RuntimeException, std::exception )
1075 ensureAlive();
1076 return NULL;
1079 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleSummary()
1080 throw( RuntimeException, std::exception )
1082 ensureAlive();
1083 return NULL;
1086 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 nColumn )
1087 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
1089 return isAccessibleColumnSelected( nColumn );
1092 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
1093 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
1095 SolarMutexGuard aGuard;
1096 ensureAlive();
1097 ensureValidPosition( nRow, nColumn );
1098 return implGetIndex( nRow, nColumn );
1101 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRow( sal_Int32 nChildIndex )
1102 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
1104 SolarMutexGuard aGuard;
1105 ensureAlive();
1106 ensureValidIndex( nChildIndex );
1107 return implGetRow( nChildIndex );
1110 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumn( sal_Int32 nChildIndex )
1111 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
1113 SolarMutexGuard aGuard;
1114 ensureAlive();
1115 ensureValidIndex( nChildIndex );
1116 return implGetColumn( nChildIndex );
1119 // XAccessibleSelection -------------------------------------------------------
1121 void SAL_CALL ScAccessibleCsvGrid::selectAccessibleChild( sal_Int32 nChildIndex )
1122 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
1124 SolarMutexGuard aGuard;
1125 ensureAlive();
1126 ensureValidIndex( nChildIndex );
1127 sal_Int32 nColumn = implGetColumn( nChildIndex );
1128 if( nChildIndex == 0 )
1129 implGetGrid().SelectAll();
1130 else
1131 implSelectColumn( nColumn, true );
1134 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleChildSelected( sal_Int32 nChildIndex )
1135 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
1137 SolarMutexGuard aGuard;
1138 ensureAlive();
1139 ensureValidIndex( nChildIndex );
1140 sal_Int32 nColumn = implGetColumn( nChildIndex );
1141 return implIsColumnSelected( nColumn );
1144 void SAL_CALL ScAccessibleCsvGrid::clearAccessibleSelection() throw( RuntimeException, std::exception )
1146 SolarMutexGuard aGuard;
1147 ensureAlive();
1148 implGetGrid().SelectAll( false );
1151 void SAL_CALL ScAccessibleCsvGrid::selectAllAccessibleChildren() throw( RuntimeException, std::exception )
1153 selectAccessibleChild( 0 );
1156 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChildCount() throw( RuntimeException, std::exception )
1158 SolarMutexGuard aGuard;
1159 ensureAlive();
1160 return implGetRowCount() * implGetSelColumnCount();
1163 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
1164 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
1166 SolarMutexGuard aGuard;
1167 ensureAlive();
1168 sal_Int32 nColumns = implGetSelColumnCount();
1169 if( nColumns == 0 )
1170 throw IndexOutOfBoundsException();
1172 sal_Int32 nRow = nSelectedChildIndex / nColumns;
1173 sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns );
1174 return getAccessibleCellAt( nRow, nColumn );
1177 void SAL_CALL ScAccessibleCsvGrid::deselectAccessibleChild( sal_Int32 nSelectedChildIndex )
1178 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
1180 SolarMutexGuard aGuard;
1181 ensureAlive();
1182 sal_Int32 nColumns = implGetSelColumnCount();
1183 if( nColumns == 0 )
1184 throw IndexOutOfBoundsException();
1186 sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns );
1187 ensureValidPosition( nSelectedChildIndex / nColumns, nColumn );
1188 if( nColumn > 0 )
1189 implSelectColumn( nColumn, false );
1192 // XInterface -----------------------------------------------------------------
1194 Any SAL_CALL ScAccessibleCsvGrid::queryInterface( const ::com::sun::star::uno::Type& rType )
1195 throw( RuntimeException, std::exception )
1197 Any aAny( ScAccessibleCsvGridImpl::queryInterface( rType ) );
1198 return aAny.hasValue() ? aAny : ScAccessibleCsvControl::queryInterface( rType );
1201 void SAL_CALL ScAccessibleCsvGrid::acquire() throw ()
1203 ScAccessibleCsvControl::acquire();
1206 void SAL_CALL ScAccessibleCsvGrid::release() throw ()
1208 ScAccessibleCsvControl::release();
1211 // XServiceInfo ---------------------------------------------------------------
1213 OUString SAL_CALL ScAccessibleCsvGrid::getImplementationName() throw( RuntimeException, std::exception )
1215 return OUString( GRID_IMPL_NAME );
1218 // XTypeProvider --------------------------------------------------------------
1220 Sequence< ::com::sun::star::uno::Type > SAL_CALL ScAccessibleCsvGrid::getTypes() throw( RuntimeException, std::exception )
1222 Sequence< ::com::sun::star::uno::Type > aSeq( 2 );
1223 aSeq[ 0 ] = cppu::UnoType<XAccessibleTable>::get();
1224 aSeq[ 1 ] = cppu::UnoType<XAccessibleSelection>::get();
1225 return ::comphelper::concatSequences( ScAccessibleCsvControl::getTypes(), aSeq );
1228 Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvGrid::getImplementationId() throw( RuntimeException, std::exception )
1230 return css::uno::Sequence<sal_Int8>();
1233 // events ---------------------------------------------------------------------
1235 void ScAccessibleCsvGrid::SendFocusEvent( bool bFocused )
1237 ScAccessibleCsvControl::SendFocusEvent( bFocused );
1239 AccessibleEventObject aEvent;
1240 aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
1241 aEvent.Source = Reference< XAccessible >( this );
1242 (bFocused ? aEvent.NewValue : aEvent.OldValue) <<=
1243 getAccessibleCellAt( 0, lcl_GetApiColumn( implGetGrid().GetFocusColumn() ) );
1244 CommitChange( aEvent );
1247 void ScAccessibleCsvGrid::SendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows )
1249 if( nFirstColumn <= nLastColumn )
1251 AccessibleTableModelChange aModelChange(
1252 AccessibleTableModelChangeType::UPDATE, 0, bAllRows ? implGetRowCount() - 1 : 0,
1253 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1254 AccessibleEventObject aEvent;
1255 aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
1256 aEvent.Source = Reference< XAccessible >( this );
1257 aEvent.NewValue <<= aModelChange;
1258 CommitChange( aEvent );
1262 void ScAccessibleCsvGrid::SendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
1264 if( nFirstColumn <= nLastColumn )
1266 AccessibleTableModelChange aModelChange(
1267 AccessibleTableModelChangeType::INSERT, 0, implGetRowCount() - 1,
1268 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1269 AccessibleEventObject aEvent;
1270 aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
1271 aEvent.Source = Reference< XAccessible >( this );
1272 aEvent.NewValue <<= aModelChange;
1273 CommitChange( aEvent );
1277 void ScAccessibleCsvGrid::SendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
1279 if( nFirstColumn <= nLastColumn )
1281 AccessibleTableModelChange aModelChange(
1282 AccessibleTableModelChangeType::DELETE, 0, implGetRowCount() - 1,
1283 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1284 AccessibleEventObject aEvent;
1285 aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
1286 aEvent.Source = Reference< XAccessible >( this );
1287 aEvent.NewValue <<= aModelChange;
1288 CommitChange( aEvent );
1292 // helpers --------------------------------------------------------------------
1294 OUString SAL_CALL ScAccessibleCsvGrid::createAccessibleName() throw( RuntimeException, std::exception )
1296 return OUString( ScResId( STR_ACC_CSVGRID_NAME ) );
1299 OUString SAL_CALL ScAccessibleCsvGrid::createAccessibleDescription() throw( RuntimeException )
1301 return OUString( ScResId( STR_ACC_CSVGRID_DESCR ) );
1304 void ScAccessibleCsvGrid::ensureValidIndex( sal_Int32 nIndex ) const
1305 throw( IndexOutOfBoundsException )
1307 if( (nIndex < 0) || (nIndex >= implGetCellCount()) )
1308 throw IndexOutOfBoundsException();
1311 void ScAccessibleCsvGrid::ensureValidPosition( sal_Int32 nRow, sal_Int32 nColumn ) const
1312 throw( IndexOutOfBoundsException )
1314 if( (nRow < 0) || (nRow >= implGetRowCount()) || (nColumn < 0) || (nColumn >= implGetColumnCount()) )
1315 throw IndexOutOfBoundsException();
1318 ScCsvGrid& ScAccessibleCsvGrid::implGetGrid() const
1320 return static_cast< ScCsvGrid& >( implGetControl() );
1323 bool ScAccessibleCsvGrid::implIsColumnSelected( sal_Int32 nColumn ) const
1325 return (nColumn > 0) && implGetGrid().IsSelected( lcl_GetGridColumn( nColumn ) );
1328 void ScAccessibleCsvGrid::implSelectColumn( sal_Int32 nColumn, bool bSelect )
1330 if( nColumn > 0 )
1331 implGetGrid().Select( lcl_GetGridColumn( nColumn ), bSelect );
1334 sal_Int32 ScAccessibleCsvGrid::implGetRowCount() const
1336 return static_cast< sal_Int32 >( implGetGrid().GetLastVisLine() - implGetGrid().GetFirstVisLine() + 2 );
1339 sal_Int32 ScAccessibleCsvGrid::implGetColumnCount() const
1341 return static_cast< sal_Int32 >( implGetGrid().GetColumnCount() + 1 );
1344 sal_Int32 ScAccessibleCsvGrid::implGetSelColumnCount() const
1346 ScCsvGrid& rGrid = implGetGrid();
1347 sal_Int32 nCount = 0;
1348 for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) )
1349 ++nCount;
1350 return nCount;
1353 sal_Int32 ScAccessibleCsvGrid::implGetSelColumn( sal_Int32 nSelColumn ) const
1355 ScCsvGrid& rGrid = implGetGrid();
1356 sal_Int32 nColumn = 0;
1357 for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) )
1359 if( nColumn == nSelColumn )
1360 return static_cast< sal_Int32 >( nColIx + 1 );
1361 ++nColumn;
1363 return 0;
1366 OUString ScAccessibleCsvGrid::implGetCellText( sal_Int32 nRow, sal_Int32 nColumn ) const
1368 ScCsvGrid& rGrid = implGetGrid();
1369 sal_Int32 nLine = nRow + rGrid.GetFirstVisLine() - 1;
1370 OUString aCellStr;
1371 if( (nColumn > 0) && (nRow > 0) )
1372 aCellStr = rGrid.GetCellText( lcl_GetGridColumn( nColumn ), nLine );
1373 else if( nRow > 0 )
1374 aCellStr = OUString::number( nLine + 1L );
1375 else if( nColumn > 0 )
1376 aCellStr = rGrid.GetColumnTypeName( lcl_GetGridColumn( nColumn ) );
1377 return aCellStr;
1380 ScAccessibleCsvControl* ScAccessibleCsvGrid::implCreateCellObj( sal_Int32 nRow, sal_Int32 nColumn ) const
1382 return new ScAccessibleCsvCell( implGetGrid(), implGetCellText( nRow, nColumn ), nRow, nColumn );
1385 ScAccessibleCsvCell::ScAccessibleCsvCell(
1386 ScCsvGrid& rGrid,
1387 const OUString& rCellText,
1388 sal_Int32 nRow, sal_Int32 nColumn ) :
1389 ScAccessibleCsvControl( rGrid.GetAccessible(), rGrid, nCellRole ),
1390 AccessibleStaticTextBase( SvxEditSourcePtr() ),
1391 maCellText( rCellText ),
1392 mnLine( nRow ? (nRow + rGrid.GetFirstVisLine() - 1) : CSV_LINE_HEADER ),
1393 mnColumn( lcl_GetGridColumn( nColumn ) ),
1394 mnIndex( nRow * (rGrid.GetColumnCount() + 1) + nColumn )
1396 SetEditSource( implCreateEditSource() );
1399 ScAccessibleCsvCell::~ScAccessibleCsvCell()
1403 void SAL_CALL ScAccessibleCsvCell::disposing()
1405 SolarMutexGuard aGuard;
1406 SetEditSource( SvxEditSourcePtr() );
1407 ScAccessibleCsvControl::disposing();
1410 // XAccessibleComponent -------------------------------------------------------
1412 void SAL_CALL ScAccessibleCsvCell::grabFocus() throw( RuntimeException, std::exception )
1414 SolarMutexGuard aGuard;
1415 ensureAlive();
1416 ScCsvGrid& rGrid = implGetGrid();
1417 rGrid.Execute( CSVCMD_MOVEGRIDCURSOR, rGrid.GetColumnPos( mnColumn ) );
1420 sal_Int32 SAL_CALL ScAccessibleCsvCell::getForeground( )
1421 throw (RuntimeException, std::exception)
1423 SolarMutexGuard aGuard;
1424 ensureAlive();
1425 return implGetGrid().GetSettings().GetStyleSettings().GetButtonTextColor().GetColor();
1428 sal_Int32 SAL_CALL ScAccessibleCsvCell::getBackground( )
1429 throw (RuntimeException, std::exception)
1431 SolarMutexGuard aGuard;
1432 ensureAlive();
1433 return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
1436 // XAccessibleContext -----------------------------------------------------
1438 sal_Int32 SAL_CALL ScAccessibleCsvCell::getAccessibleChildCount() throw( RuntimeException, std::exception )
1440 return AccessibleStaticTextBase::getAccessibleChildCount();
1443 Reference< XAccessible > SAL_CALL ScAccessibleCsvCell::getAccessibleChild( sal_Int32 nIndex )
1444 throw( IndexOutOfBoundsException, RuntimeException, std::exception )
1446 return AccessibleStaticTextBase::getAccessibleChild( nIndex );
1449 sal_Int32 SAL_CALL ScAccessibleCsvCell::getAccessibleIndexInParent() throw( RuntimeException, std::exception )
1451 SolarMutexGuard aGuard;
1452 ensureAlive();
1453 return mnIndex;
1456 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvCell::getAccessibleRelationSet()
1457 throw( RuntimeException, std::exception )
1459 SolarMutexGuard aGuard;
1460 ensureAlive();
1461 return new AccessibleRelationSetHelper();
1464 Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvCell::getAccessibleStateSet()
1465 throw( RuntimeException, std::exception )
1467 SolarMutexGuard aGuard;
1468 AccessibleStateSetHelper* pStateSet = implCreateStateSet();
1469 if( implIsAlive() )
1471 const ScCsvGrid& rGrid = implGetGrid();
1472 pStateSet->AddState( AccessibleStateType::SINGLE_LINE );
1473 if( mnColumn != CSV_COLUMN_HEADER )
1474 pStateSet->AddState( AccessibleStateType::SELECTABLE );
1475 if( rGrid.HasFocus() && (rGrid.GetFocusColumn() == mnColumn) && (mnLine == CSV_LINE_HEADER) )
1476 pStateSet->AddState( AccessibleStateType::ACTIVE );
1477 if( rGrid.IsSelected( mnColumn ) )
1478 pStateSet->AddState( AccessibleStateType::SELECTED );
1480 return pStateSet;
1483 // XInterface -----------------------------------------------------------------
1485 IMPLEMENT_FORWARD_XINTERFACE2( ScAccessibleCsvCell, ScAccessibleCsvControl, AccessibleStaticTextBase )
1487 // XTypeProvider --------------------------------------------------------------
1489 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScAccessibleCsvCell, ScAccessibleCsvControl, AccessibleStaticTextBase )
1491 // XServiceInfo ---------------------------------------------------------------
1493 OUString SAL_CALL ScAccessibleCsvCell::getImplementationName() throw( RuntimeException, std::exception )
1495 return OUString( CELL_IMPL_NAME );
1498 // helpers --------------------------------------------------------------------
1500 Rectangle ScAccessibleCsvCell::GetBoundingBoxOnScreen() const throw( RuntimeException, std::exception )
1502 SolarMutexGuard aGuard;
1503 ensureAlive();
1504 Rectangle aRect( implGetBoundingBox() );
1505 aRect.SetPos( implGetAbsPos( aRect.TopLeft() ) );
1506 return aRect;
1509 Rectangle ScAccessibleCsvCell::GetBoundingBox() const throw( RuntimeException, std::exception )
1511 SolarMutexGuard aGuard;
1512 ensureAlive();
1513 return implGetBoundingBox();
1516 OUString SAL_CALL ScAccessibleCsvCell::createAccessibleName() throw( RuntimeException, std::exception )
1518 return maCellText;
1521 OUString SAL_CALL ScAccessibleCsvCell::createAccessibleDescription() throw( RuntimeException )
1523 return OUString();
1526 ScCsvGrid& ScAccessibleCsvCell::implGetGrid() const
1528 return static_cast< ScCsvGrid& >( implGetControl() );
1531 Point ScAccessibleCsvCell::implGetRealPos() const
1533 ScCsvGrid& rGrid = implGetGrid();
1534 return Point(
1535 (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrX() : rGrid.GetColumnX( mnColumn ),
1536 (mnLine == CSV_LINE_HEADER) ? 0 : rGrid.GetY( mnLine ) );
1539 sal_uInt32 ScAccessibleCsvCell::implCalcPixelWidth(sal_uInt32 nChars) const
1541 ScCsvGrid& rGrid = implGetGrid();
1542 return rGrid.GetCharWidth() * nChars;
1545 Size ScAccessibleCsvCell::implGetRealSize() const
1547 ScCsvGrid& rGrid = implGetGrid();
1548 return Size(
1549 (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrWidth() : implCalcPixelWidth( rGrid.GetColumnWidth( mnColumn ) ),
1550 (mnLine == CSV_LINE_HEADER) ? rGrid.GetHdrHeight() : rGrid.GetLineHeight() );
1553 Rectangle ScAccessibleCsvCell::implGetBoundingBox() const
1555 ScCsvGrid& rGrid = implGetGrid();
1556 Rectangle aClipRect( Point( 0, 0 ), rGrid.GetSizePixel() );
1557 if( mnColumn != CSV_COLUMN_HEADER )
1559 aClipRect.Left() = rGrid.GetFirstX();
1560 aClipRect.Right() = rGrid.GetLastX();
1562 if( mnLine != CSV_LINE_HEADER )
1563 aClipRect.Top() = rGrid.GetHdrHeight();
1565 Rectangle aRect( implGetRealPos(), implGetRealSize() );
1566 aRect.Intersection( aClipRect );
1567 if( (aRect.GetWidth() <= 0) || (aRect.GetHeight() <= 0) )
1568 aRect.SetSize( Size( -1, -1 ) );
1569 return aRect;
1572 ::std::unique_ptr< SvxEditSource > ScAccessibleCsvCell::implCreateEditSource()
1574 ScCsvGrid& rGrid = implGetGrid();
1575 Rectangle aBoundRect( implGetBoundingBox() );
1576 aBoundRect -= implGetRealPos();
1578 ::std::unique_ptr< ScAccessibleTextData > pCsvTextData( new ScAccessibleCsvTextData(
1579 &rGrid, rGrid.GetEditEngine(), maCellText, aBoundRect, implGetRealSize() ) );
1581 ::std::unique_ptr< SvxEditSource > pEditSource( new ScAccessibilityEditSource( std::move(pCsvTextData) ) );
1582 return pEditSource;
1585 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */