tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / Accessibility / AccessibleCsvControl.cxx
blobaf0fb44c256ad8b0880d5b71e865a841900351b1
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 <memory>
21 #include <sal/config.h>
23 #include <utility>
25 #include <AccessibleCsvControl.hxx>
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 <com/sun/star/lang/IndexOutOfBoundsException.hpp>
33 #include <unotools/accessiblerelationsethelper.hxx>
34 #include <comphelper/sequence.hxx>
35 #include <scitems.hxx>
36 #include <editeng/fontitem.hxx>
37 #include <editeng/fhgtitem.hxx>
38 #include <editeng/langitem.hxx>
39 #include <csvtablebox.hxx>
40 #include <csvcontrol.hxx>
41 #include <csvruler.hxx>
42 #include <csvgrid.hxx>
43 #include <AccessibleText.hxx>
44 #include <editsrc.hxx>
45 #include <scresid.hxx>
46 #include <strings.hrc>
47 #include <scmod.hxx>
48 #include <svtools/colorcfg.hxx>
49 #include <vcl/svapp.hxx>
50 #include <vcl/settings.hxx>
51 #include <o3tl/string_view.hxx>
53 using ::utl::AccessibleRelationSetHelper;
54 using ::accessibility::AccessibleStaticTextBase;
55 using ::com::sun::star::uno::Any;
56 using ::com::sun::star::uno::Reference;
57 using ::com::sun::star::uno::Sequence;
58 using ::com::sun::star::uno::RuntimeException;
59 using ::com::sun::star::uno::XInterface;
60 using ::com::sun::star::lang::IndexOutOfBoundsException;
61 using ::com::sun::star::beans::PropertyValue;
62 using namespace ::com::sun::star::accessibility;
64 const sal_Unicode cRulerDot = '.';
65 const sal_Unicode cRulerLine = '|';
67 const sal_Int32 CSV_LINE_HEADER = CSV_POS_INVALID;
68 const sal_uInt32 CSV_COLUMN_HEADER = CSV_COLUMN_INVALID;
70 ScAccessibleCsvControl::ScAccessibleCsvControl(ScCsvControl& rControl)
71 : mpControl(&rControl)
75 ScAccessibleCsvControl::~ScAccessibleCsvControl()
77 ensureDisposed();
80 void SAL_CALL ScAccessibleCsvControl::disposing()
82 SolarMutexGuard aGuard;
83 mpControl = nullptr;
84 comphelper::OAccessibleComponentHelper::disposing();
87 // XAccessibleComponent -------------------------------------------------------
89 Reference< XAccessible > SAL_CALL ScAccessibleCsvControl::getAccessibleAtPoint( const css::awt::Point& /* rPoint */ )
91 ensureAlive();
92 return nullptr;
95 void SAL_CALL ScAccessibleCsvControl::grabFocus()
97 SolarMutexGuard aGuard;
98 ensureAlive();
99 implGetControl().GrabFocus();
102 // events ---------------------------------------------------------------------
104 void ScAccessibleCsvControl::SendFocusEvent( bool bFocused )
106 Any aOldAny, aNewAny;
107 if (bFocused)
108 aNewAny <<= AccessibleStateType::FOCUSED;
109 else
110 aOldAny <<= AccessibleStateType::FOCUSED;
111 NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny);
114 void ScAccessibleCsvControl::SendCaretEvent()
116 OSL_FAIL( "ScAccessibleCsvControl::SendCaretEvent - Illegal call" );
119 void ScAccessibleCsvControl::SendVisibleEvent()
121 NotifyAccessibleEvent(AccessibleEventId::VISIBLE_DATA_CHANGED, Any(), Any());
124 void ScAccessibleCsvControl::SendSelectionEvent()
126 NotifyAccessibleEvent(AccessibleEventId::SELECTION_CHANGED, Any(), Any());
129 void ScAccessibleCsvControl::SendTableUpdateEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */, bool /* bAllRows */ )
131 OSL_FAIL( "ScAccessibleCsvControl::SendTableUpdateEvent - Illegal call" );
134 void ScAccessibleCsvControl::SendInsertColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ )
136 OSL_FAIL( "ScAccessibleCsvControl::SendInsertColumnEvent - Illegal call" );
139 void ScAccessibleCsvControl::SendRemoveColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ )
141 OSL_FAIL( "ScAccessibleCsvControl::SendRemoveColumnEvent - Illegal call" );
144 // helpers --------------------------------------------------------------------
146 css::awt::Rectangle ScAccessibleCsvControl::implGetBounds()
148 SolarMutexGuard aGuard;
149 ensureAlive();
150 Size aOutSize(implGetControl().GetOutputSizePixel());
151 return css::awt::Rectangle(0, 0, aOutSize.Width(), aOutSize.Height());
154 ScCsvControl& ScAccessibleCsvControl::implGetControl() const
156 assert(mpControl && "ScAccessibleCsvControl::implGetControl - missing control");
157 return *mpControl;
160 sal_Int64 ScAccessibleCsvControl::implCreateStateSet()
162 SolarMutexGuard aGuard;
163 sal_Int64 nStateSet = 0;
164 if (isAlive())
166 const ScCsvControl& rCtrl = implGetControl();
167 nStateSet |= AccessibleStateType::OPAQUE;
168 if( rCtrl.IsEnabled() )
169 nStateSet |= AccessibleStateType::ENABLED;
170 if( rCtrl.IsReallyVisible() )
171 nStateSet |= AccessibleStateType::SHOWING;
172 if( rCtrl.IsVisible() )
173 nStateSet |= AccessibleStateType::VISIBLE;
175 else
176 nStateSet |= AccessibleStateType::DEFUNC;
177 return nStateSet;
180 // Ruler ======================================================================
182 /** Converts a ruler cursor position to API text index. */
183 static sal_Int32 lcl_GetApiPos( sal_Int32 nRulerPos )
185 sal_Int32 nApiPos = nRulerPos;
186 sal_Int32 nStart = (nRulerPos - 1) / 10;
187 sal_Int32 nExp = 1;
188 while( nStart >= nExp )
190 nApiPos += nStart - nExp + 1;
191 nExp *= 10;
193 return ::std::max( nApiPos, static_cast<sal_Int32>(0) );
196 /** Converts an API text index to a ruler cursor position. */
197 static sal_Int32 lcl_GetRulerPos( sal_Int32 nApiPos )
199 sal_Int32 nDiv = 10;
200 sal_Int32 nExp = 10;
201 sal_Int32 nRulerPos = 0;
202 sal_Int32 nApiBase = 0;
203 sal_Int32 nApiLimit = 10;
204 while( nApiPos >= nApiLimit )
206 ++nDiv;
207 nRulerPos = nExp;
208 nExp *= 10;
209 nApiBase = nApiLimit;
210 nApiLimit = lcl_GetApiPos( nExp );
212 sal_Int32 nRelPos = nApiPos - nApiBase;
213 return nRulerPos + nRelPos / nDiv * 10 + ::std::max<sal_Int32>( nRelPos % nDiv - nDiv + 10, 0 );
216 /** Expands the sequence's size and returns the base index of the new inserted elements. */
217 static sal_Int32 lcl_ExpandSequence( Sequence< PropertyValue >& rSeq, sal_Int32 nExp )
219 OSL_ENSURE( nExp > 0, "lcl_ExpandSequence - invalid value" );
220 rSeq.realloc( rSeq.getLength() + nExp );
221 return rSeq.getLength() - nExp;
224 /** Fills the property value rVal with the specified name and value from the item. */
225 static void lcl_FillProperty( PropertyValue& rVal, const OUString& rPropName, const SfxPoolItem& rItem, sal_uInt8 nMID )
227 rVal.Name = rPropName;
228 rItem.QueryValue( rVal.Value, nMID );
231 /** Fills the sequence with all font attributes of rFont. */
232 static void lcl_FillFontAttributes( Sequence< PropertyValue >& rSeq, const vcl::Font& rFont )
234 SvxFontItem aFontItem( rFont.GetFamilyType(), rFont.GetFamilyName(), rFont.GetStyleName(), rFont.GetPitch(), rFont.GetCharSet(), ATTR_FONT );
235 SvxFontHeightItem aHeightItem( rFont.GetFontSize().Height(), 100, ATTR_FONT_HEIGHT );
236 SvxLanguageItem aLangItem( rFont.GetLanguage(), ATTR_FONT_LANGUAGE );
238 sal_Int32 nIndex = lcl_ExpandSequence( rSeq, 7 );
239 auto pSeq = rSeq.getArray();
240 lcl_FillProperty( pSeq[ nIndex++ ], u"CharFontName"_ustr, aFontItem, MID_FONT_FAMILY_NAME );
241 lcl_FillProperty( pSeq[ nIndex++ ], u"CharFontFamily"_ustr, aFontItem, MID_FONT_FAMILY );
242 lcl_FillProperty( pSeq[ nIndex++ ], u"CharFontStyleName"_ustr, aFontItem, MID_FONT_STYLE_NAME );
243 lcl_FillProperty( pSeq[ nIndex++ ], u"CharFontCharSet"_ustr, aFontItem, MID_FONT_PITCH );
244 lcl_FillProperty( pSeq[ nIndex++ ], u"CharFontPitch"_ustr, aFontItem, MID_FONT_CHAR_SET );
245 lcl_FillProperty( pSeq[ nIndex++ ], u"CharHeight"_ustr, aHeightItem, MID_FONTHEIGHT );
246 lcl_FillProperty( pSeq[ nIndex++ ], u"CharLocale"_ustr, aLangItem, MID_LANG_LOCALE );
249 ScAccessibleCsvRuler::ScAccessibleCsvRuler(ScCsvRuler& rRuler)
250 : ImplInheritanceHelper(rRuler)
252 constructStringBuffer();
255 ScAccessibleCsvRuler::~ScAccessibleCsvRuler()
257 ensureDisposed();
260 // XAccessibleComponent -----------------------------------------------------
262 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getForeground( )
264 SolarMutexGuard aGuard;
265 ensureAlive();
266 return sal_Int32(Application::GetSettings().GetStyleSettings().GetLabelTextColor());
269 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getBackground( )
271 SolarMutexGuard aGuard;
272 ensureAlive();
273 return sal_Int32(Application::GetSettings().GetStyleSettings().GetFaceColor());
276 // XAccessibleContext ---------------------------------------------------------
278 sal_Int64 SAL_CALL ScAccessibleCsvRuler::getAccessibleChildCount()
280 ensureAlive();
281 return 0;
284 Reference< XAccessible > SAL_CALL ScAccessibleCsvRuler::getAccessibleChild( sal_Int64 /* nIndex */ )
286 ensureAlive();
287 throw IndexOutOfBoundsException();
290 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvRuler::getAccessibleRelationSet()
292 SolarMutexGuard aGuard;
293 ensureAlive();
294 rtl::Reference<AccessibleRelationSetHelper> pRelationSet = new AccessibleRelationSetHelper();
296 ScCsvRuler& rRuler = implGetRuler();
297 ScCsvTableBox* pTableBox = rRuler.GetTableBox();
298 ScCsvGrid& rGrid = pTableBox->GetGrid();
300 css::uno::Reference<css::accessibility::XAccessible> xAccObj(static_cast<ScAccessibleCsvGrid*>(rGrid.GetAccessible()));
301 if( xAccObj.is() )
303 Sequence<Reference<css::accessibility::XAccessible>> aSeq{ xAccObj };
304 pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType_CONTROLLER_FOR, aSeq ) );
307 return pRelationSet;
310 sal_Int64 SAL_CALL ScAccessibleCsvRuler::getAccessibleStateSet()
312 SolarMutexGuard aGuard;
313 sal_Int64 nStateSet = implCreateStateSet();
314 if( isAlive() )
316 nStateSet |= AccessibleStateType::FOCUSABLE;
317 nStateSet |= AccessibleStateType::SINGLE_LINE;
318 if( implGetRuler().HasFocus() )
319 nStateSet |= AccessibleStateType::FOCUSED;
321 return nStateSet;
324 // XAccessibleText ------------------------------------------------------------
326 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCaretPosition()
328 SolarMutexGuard aGuard;
329 ensureAlive();
330 return lcl_GetApiPos( implGetRuler().GetRulerCursorPos() );
333 sal_Bool SAL_CALL ScAccessibleCsvRuler::setCaretPosition( sal_Int32 nIndex )
335 SolarMutexGuard aGuard;
336 ensureAlive();
337 ensureValidIndex( nIndex );
338 ScCsvRuler& rRuler = implGetRuler();
339 sal_Int32 nOldCursor = rRuler.GetRulerCursorPos();
340 rRuler.Execute( CSVCMD_MOVERULERCURSOR, lcl_GetRulerPos( nIndex ) );
341 return rRuler.GetRulerCursorPos() != nOldCursor;
344 sal_Unicode SAL_CALL ScAccessibleCsvRuler::getCharacter( sal_Int32 nIndex )
346 SolarMutexGuard aGuard;
347 ensureAlive();
348 ensureValidIndex( nIndex );
349 return maBuffer[nIndex];
352 Sequence< PropertyValue > SAL_CALL ScAccessibleCsvRuler::getCharacterAttributes( sal_Int32 nIndex,
353 const css::uno::Sequence< OUString >& /* aRequestedAttributes */ )
355 SolarMutexGuard aGuard;
356 ensureAlive();
357 ensureValidIndexWithEnd( nIndex );
358 Sequence< PropertyValue > aSeq;
359 lcl_FillFontAttributes( aSeq, implGetRuler().GetDrawingArea()->get_ref_device().GetFont() );
360 return aSeq;
363 css::awt::Rectangle SAL_CALL ScAccessibleCsvRuler::getCharacterBounds( sal_Int32 nIndex )
365 SolarMutexGuard aGuard;
366 ensureAlive();
367 ensureValidIndexWithEnd( nIndex );
368 ScCsvRuler& rRuler = implGetRuler();
369 Point aPos( rRuler.GetX( lcl_GetRulerPos( nIndex ) ) - rRuler.GetCharWidth() / 2, 0 );
370 css::awt::Rectangle aRect( aPos.X(), aPos.Y(), rRuler.GetCharWidth(), rRuler.GetOutputSizePixel().Height() );
371 // do not return rectangle out of window
372 sal_Int32 nWidth = rRuler.GetOutputSizePixel().Width();
373 if( aRect.X >= nWidth )
374 throw IndexOutOfBoundsException();
375 if( aRect.X + aRect.Width > nWidth )
376 aRect.Width = nWidth - aRect.X;
377 return aRect;
380 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCharacterCount()
382 SolarMutexGuard aGuard;
383 ensureAlive();
384 return implGetTextLength();
387 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getIndexAtPoint( const css::awt::Point& rPoint )
389 SolarMutexGuard aGuard;
390 ensureAlive();
391 ScCsvRuler& rRuler = implGetRuler();
392 // use object's coordinate system, convert to API position
393 return lcl_GetApiPos( ::std::clamp( rRuler.GetPosFromX( rPoint.X ), sal_Int32(0), rRuler.GetPosCount() ) );
396 OUString SAL_CALL ScAccessibleCsvRuler::getSelectedText()
398 ensureAlive();
399 return OUString();
402 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionStart()
404 ensureAlive();
405 return -1;
408 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionEnd()
410 ensureAlive();
411 return -1;
414 sal_Bool SAL_CALL ScAccessibleCsvRuler::setSelection( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ )
416 ensureAlive();
417 return false;
420 OUString SAL_CALL ScAccessibleCsvRuler::getText()
422 SolarMutexGuard aGuard;
423 ensureAlive();
424 return OUString(maBuffer.subView( 0, implGetTextLength() ));
427 OUString SAL_CALL ScAccessibleCsvRuler::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
429 SolarMutexGuard aGuard;
430 ensureAlive();
431 ensureValidRange( nStartIndex, nEndIndex );
432 return OUString( maBuffer.getStr() + nStartIndex, nEndIndex - nStartIndex );
435 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextAtIndex( sal_Int32 nIndex, sal_Int16 nTextType )
437 SolarMutexGuard aGuard;
438 ensureAlive();
440 TextSegment aResult;
441 aResult.SegmentStart = -1;
442 aResult.SegmentEnd = -1;
444 if( (nIndex == implGetTextLength()) && (nTextType != AccessibleTextType::LINE) )
445 return aResult;
447 ensureValidIndex( nIndex );
449 OUStringBuffer aResultText; // will be assigned to aResult.SegmentText below
450 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
452 switch( nTextType )
454 // single character
455 case AccessibleTextType::CHARACTER:
457 aResult.SegmentStart = nIndex;
458 aResult.SegmentEnd = nIndex;
459 o3tl::iterateCodePoints(maBuffer, &aResult.SegmentEnd);
460 for (; nIndex < aResult.SegmentEnd; nIndex++)
461 aResultText.append(maBuffer[nIndex]);
463 break;
465 // entire number or single dot/line
466 case AccessibleTextType::WORD:
467 case AccessibleTextType::GLYPH:
468 aResult.SegmentStart = nIndex;
469 if( nRulerPos % 10 )
470 aResultText.append(maBuffer[nIndex]);
471 else
472 aResultText.append( nRulerPos ); // string representation of sal_Int32!!!
473 break;
475 // entire text
476 case AccessibleTextType::SENTENCE:
477 case AccessibleTextType::PARAGRAPH:
478 case AccessibleTextType::LINE:
479 aResult.SegmentStart = 0;
480 aResultText.append( maBuffer.getStr(), implGetTextLength() );
481 break;
483 // equal-formatted text
484 case AccessibleTextType::ATTRIBUTE_RUN:
486 sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex );
487 sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex );
488 aResult.SegmentStart = nFirstIndex;
489 aResultText.append( maBuffer.getStr() + nFirstIndex, nLastIndex - nFirstIndex + 1 );
491 break;
493 default:
494 throw RuntimeException();
497 aResult.SegmentText = aResultText.makeStringAndClear();
498 aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
499 return aResult;
502 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 nTextType )
504 SolarMutexGuard aGuard;
505 ensureAlive();
506 ensureValidIndexWithEnd( nIndex );
508 TextSegment aResult;
509 aResult.SegmentStart = -1;
510 aResult.SegmentEnd = -1;
512 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
514 switch( nTextType )
516 // single character
517 case AccessibleTextType::CHARACTER:
518 if( nIndex > 0 )
520 o3tl::iterateCodePoints(maBuffer, &nIndex, -1);
521 aResult = getTextAtIndex(nIndex, nTextType);
523 // else empty
524 break;
526 // entire number or single dot/line
527 case AccessibleTextType::WORD:
528 case AccessibleTextType::GLYPH:
529 if( nRulerPos > 0 )
530 aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos - 1 ), nTextType );
531 // else empty
532 break;
534 // entire text
535 case AccessibleTextType::SENTENCE:
536 case AccessibleTextType::PARAGRAPH:
537 case AccessibleTextType::LINE:
538 // empty
539 break;
541 // equal-formatted text
542 case AccessibleTextType::ATTRIBUTE_RUN:
544 sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex );
545 if( nFirstIndex > 0 )
546 aResult = getTextAtIndex( nFirstIndex - 1, nTextType );
547 // else empty
549 break;
551 default:
552 throw RuntimeException();
554 return aResult;
557 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 nTextType )
559 SolarMutexGuard aGuard;
560 ensureAlive();
561 ensureValidIndexWithEnd( nIndex );
563 TextSegment aResult;
564 aResult.SegmentStart = -1;
565 aResult.SegmentEnd = -1;
567 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
568 sal_Int32 nLastValid = implGetTextLength();
570 switch( nTextType )
572 // single character
573 case AccessibleTextType::CHARACTER:
574 if( nIndex < nLastValid )
576 o3tl::iterateCodePoints(maBuffer, &nIndex);
577 aResult = getTextAtIndex(nIndex, nTextType);
579 // else empty
580 break;
582 // entire number or single dot/line
583 case AccessibleTextType::WORD:
584 case AccessibleTextType::GLYPH:
585 if( nRulerPos < implGetRuler().GetPosCount() )
586 aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos + 1 ), nTextType );
587 // else empty
588 break;
590 // entire text
591 case AccessibleTextType::SENTENCE:
592 case AccessibleTextType::PARAGRAPH:
593 case AccessibleTextType::LINE:
594 // empty
595 break;
597 // equal-formatted text
598 case AccessibleTextType::ATTRIBUTE_RUN:
600 sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex );
601 if( nLastIndex < nLastValid )
602 aResult = getTextAtIndex( nLastIndex + 1, nTextType );
603 // else empty
605 break;
607 default:
608 throw RuntimeException();
610 return aResult;
613 sal_Bool SAL_CALL ScAccessibleCsvRuler::copyText( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ )
615 ensureAlive();
616 return false;
619 sal_Bool SAL_CALL ScAccessibleCsvRuler::scrollSubstringTo( sal_Int32 /* nStartIndex */, sal_Int32/* nEndIndex */, AccessibleScrollType /* aScrollType */ )
621 return false;
624 // events ---------------------------------------------------------------------
626 void ScAccessibleCsvRuler::SendCaretEvent()
628 sal_Int32 nPos = implGetRuler().GetRulerCursorPos();
629 if (nPos != CSV_POS_INVALID)
631 Any aOldValue, aNewValue;
632 aNewValue <<= nPos;
633 NotifyAccessibleEvent( AccessibleEventId::CARET_CHANGED, aOldValue, aNewValue );
637 // helpers --------------------------------------------------------------------
639 OUString SAL_CALL ScAccessibleCsvRuler::getAccessibleName()
641 return ScResId( STR_ACC_CSVRULER_NAME );
644 OUString SAL_CALL ScAccessibleCsvRuler::getAccessibleDescription()
646 return ScResId( STR_ACC_CSVRULER_DESCR );
649 void ScAccessibleCsvRuler::ensureValidIndex( sal_Int32 nIndex ) const
651 if( (nIndex < 0) || (nIndex >= implGetTextLength()) )
652 throw IndexOutOfBoundsException();
655 void ScAccessibleCsvRuler::ensureValidIndexWithEnd( sal_Int32 nIndex ) const
657 if( (nIndex < 0) || (nIndex > implGetTextLength()) )
658 throw IndexOutOfBoundsException();
661 void ScAccessibleCsvRuler::ensureValidRange( sal_Int32& rnStartIndex, sal_Int32& rnEndIndex ) const
663 if( rnStartIndex > rnEndIndex )
664 ::std::swap( rnStartIndex, rnEndIndex );
665 if( (rnStartIndex < 0) || (rnEndIndex > implGetTextLength()) )
666 throw IndexOutOfBoundsException();
669 ScCsvRuler& ScAccessibleCsvRuler::implGetRuler() const
671 return static_cast< ScCsvRuler& >( implGetControl() );
674 void ScAccessibleCsvRuler::constructStringBuffer()
676 SolarMutexGuard aGuard;
677 ensureAlive();
678 // extend existing string buffer to new ruler size
679 sal_Int32 nRulerCount = implGetRuler().GetPosCount();
680 sal_Int32 nRulerPos = lcl_GetRulerPos( maBuffer.getLength() );
681 for( ; nRulerPos <= nRulerCount; ++nRulerPos ) // include last position
683 switch( nRulerPos % 10 )
685 case 0: maBuffer.append( nRulerPos ); break;
686 case 5: maBuffer.append( cRulerLine ); break;
687 default: maBuffer.append( cRulerDot );
692 sal_Int32 ScAccessibleCsvRuler::implGetTextLength() const
694 return lcl_GetApiPos( implGetRuler().GetPosCount() + 1 );
697 bool ScAccessibleCsvRuler::implHasSplit( sal_Int32 nApiPos )
699 sal_Int32 nRulerPos = lcl_GetRulerPos( nApiPos );
700 return implGetRuler().HasSplit( nRulerPos ) && (nApiPos == lcl_GetApiPos( nRulerPos ));
703 sal_Int32 ScAccessibleCsvRuler::implGetFirstEqualFormatted( sal_Int32 nApiPos )
705 bool bSplit = implHasSplit( nApiPos );
706 while( (nApiPos > 0) && (implHasSplit( nApiPos - 1 ) == bSplit) )
707 --nApiPos;
708 return nApiPos;
711 sal_Int32 ScAccessibleCsvRuler::implGetLastEqualFormatted( sal_Int32 nApiPos )
713 bool bSplit = implHasSplit( nApiPos );
714 sal_Int32 nLength = implGetTextLength();
715 while( (nApiPos < nLength - 1) && (implHasSplit( nApiPos + 1 ) == bSplit) )
716 ++nApiPos;
717 return nApiPos;
720 css::uno::Reference<css::accessibility::XAccessible> SAL_CALL ScAccessibleCsvRuler::getAccessibleParent()
722 return implGetControl().GetDrawingArea()->get_accessible_parent();
725 // Grid =======================================================================
727 /** Converts a grid columnm index to an API column index. */
728 static sal_Int32 lcl_GetApiColumn( sal_uInt32 nGridColumn )
730 return (nGridColumn != CSV_COLUMN_HEADER) ? static_cast< sal_Int32 >( nGridColumn + 1 ) : 0;
733 /** Converts an API columnm index to a ScCsvGrid column index. */
734 static sal_uInt32 lcl_GetGridColumn( sal_Int32 nApiColumn )
736 return (nApiColumn > 0) ? static_cast< sal_uInt32 >( nApiColumn - 1 ) : CSV_COLUMN_HEADER;
739 ScAccessibleCsvGrid::ScAccessibleCsvGrid(ScCsvGrid& rGrid)
740 : ImplInheritanceHelper(rGrid)
744 ScAccessibleCsvGrid::~ScAccessibleCsvGrid()
746 ensureDisposed();
749 void ScAccessibleCsvGrid::disposing()
751 SolarMutexGuard aGuard;
752 for (auto& rEntry : maAccessibleChildren)
753 rEntry.second->dispose();
754 maAccessibleChildren.clear();
755 ScAccessibleCsvControl::disposing();
758 // XAccessibleComponent -------------------------------------------------------
760 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleAtPoint( const css::awt::Point& rPoint )
762 Reference< XAccessible > xRet;
763 if( containsPoint( rPoint ) )
765 SolarMutexGuard aGuard;
766 ensureAlive();
768 const ScCsvGrid& rGrid = implGetGrid();
769 // #102679#; use <= instead of <, because the offset is the size and not the point
770 sal_Int32 nColumn = ((rGrid.GetFirstX() <= rPoint.X) && (rPoint.X <= rGrid.GetLastX())) ?
771 lcl_GetApiColumn( rGrid.GetColumnFromX( rPoint.X ) ) : 0;
772 sal_Int32 nRow = (rPoint.Y >= rGrid.GetHdrHeight()) ?
773 (rGrid.GetLineFromY( rPoint.Y ) - rGrid.GetFirstVisLine() + 1) : 0;
774 xRet = getAccessibleCell(nRow, nColumn);
776 return xRet;
779 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getForeground( )
781 SolarMutexGuard aGuard;
782 ensureAlive();
783 return sal_Int32(Application::GetSettings().GetStyleSettings().GetButtonTextColor());
786 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getBackground( )
788 SolarMutexGuard aGuard;
789 ensureAlive();
790 return sal_Int32(ScModule::get()->GetColorConfig().GetColorValue(::svtools::DOCCOLOR).nColor);
793 // XAccessibleContext ---------------------------------------------------------
795 sal_Int64 SAL_CALL ScAccessibleCsvGrid::getAccessibleChildCount()
797 SolarMutexGuard aGuard;
798 ensureAlive();
799 return implGetCellCount();
802 Reference<XAccessible> ScAccessibleCsvGrid::getAccessibleCell(sal_Int32 nRow, sal_Int32 nColumn)
804 sal_Int64 nIndex = implGetIndex(nRow, nColumn);
806 XAccessibleSet::iterator aI = maAccessibleChildren.lower_bound(nIndex);
807 if (aI != maAccessibleChildren.end() && !(maAccessibleChildren.key_comp()(nIndex, aI->first)))
809 // key already exists
810 return aI->second;
812 // key does not exist
813 rtl::Reference<ScAccessibleCsvCell> xNew = implCreateCellObj(nRow, nColumn);
814 maAccessibleChildren.insert(aI, XAccessibleSet::value_type(nIndex, xNew));
815 return xNew;
818 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleChild( sal_Int64 nIndex )
820 SolarMutexGuard aGuard;
821 ensureAlive();
822 ensureValidIndex( nIndex );
824 return getAccessibleCell(implGetRow(nIndex), implGetColumn(nIndex));
827 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleRelationSet()
829 SolarMutexGuard aGuard;
830 ensureAlive();
831 rtl::Reference<AccessibleRelationSetHelper> pRelationSet = new AccessibleRelationSetHelper();
833 ScCsvGrid& rGrid = implGetGrid();
834 ScCsvTableBox* pTableBox = rGrid.GetTableBox();
835 ScCsvRuler& rRuler = pTableBox->GetRuler();
837 if (rRuler.IsVisible())
839 css::uno::Reference<css::accessibility::XAccessible> xAccObj(static_cast<ScAccessibleCsvGrid*>(rRuler.GetAccessible()));
840 if( xAccObj.is() )
842 Sequence<Reference<css::accessibility::XAccessible>> aSeq{ xAccObj };
843 pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType_CONTROLLED_BY, aSeq ) );
847 return pRelationSet;
850 sal_Int64 SAL_CALL ScAccessibleCsvGrid::getAccessibleStateSet()
852 SolarMutexGuard aGuard;
853 sal_Int64 nStateSet = implCreateStateSet();
854 if( isAlive() )
856 nStateSet |= AccessibleStateType::FOCUSABLE;
857 nStateSet |= AccessibleStateType::MULTI_SELECTABLE;
858 nStateSet |= AccessibleStateType::MANAGES_DESCENDANTS;
859 if( implGetGrid().HasFocus() )
860 nStateSet |= AccessibleStateType::FOCUSED;
862 else
863 nStateSet |= AccessibleStateType::DEFUNC;
864 return nStateSet;
867 // XAccessibleTable -----------------------------------------------------------
869 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowCount()
871 SolarMutexGuard aGuard;
872 ensureAlive();
873 return implGetRowCount();
876 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnCount()
878 SolarMutexGuard aGuard;
879 ensureAlive();
880 return implGetColumnCount();
883 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleRowDescription( sal_Int32 nRow )
885 SolarMutexGuard aGuard;
886 ensureAlive();
887 ensureValidPosition( nRow, 0 );
888 return implGetCellText( nRow, 0 );
891 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnDescription( sal_Int32 nColumn )
893 SolarMutexGuard aGuard;
894 ensureAlive();
895 ensureValidPosition( 0, nColumn );
896 return implGetCellText( 0, nColumn );
899 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
901 ensureAlive();
902 ensureValidPosition( nRow, nColumn );
903 return 1;
906 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
908 ensureAlive();
909 ensureValidPosition( nRow, nColumn );
910 return 1;
913 Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleRowHeaders()
915 ensureAlive();
916 return nullptr;
919 Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnHeaders()
921 ensureAlive();
922 return nullptr;
925 Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleRows()
927 ensureAlive();
928 return Sequence< sal_Int32 >();
931 Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleColumns()
933 SolarMutexGuard aGuard;
934 ensureAlive();
936 ScCsvGrid& rGrid = implGetGrid();
937 Sequence< sal_Int32 > aSeq( implGetColumnCount() );
938 auto pSeq = aSeq.getArray();
940 sal_Int32 nSeqIx = 0;
941 sal_uInt32 nColIx = rGrid.GetFirstSelected();
942 for( ; nColIx != CSV_COLUMN_INVALID; ++nSeqIx, nColIx = rGrid.GetNextSelected( nColIx ) )
943 pSeq[ nSeqIx ] = lcl_GetApiColumn( nColIx );
945 aSeq.realloc( nSeqIx );
946 return aSeq;
949 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleRowSelected( sal_Int32 /* nRow */ )
951 ensureAlive();
952 return false;
955 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleColumnSelected( sal_Int32 nColumn )
957 SolarMutexGuard aGuard;
958 ensureAlive();
959 ensureValidIndex( nColumn );
960 return implIsColumnSelected( nColumn );
963 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
965 SolarMutexGuard aGuard;
966 ensureAlive();
967 ensureValidPosition( nRow, nColumn );
968 return getAccessibleCell(nRow, nColumn);
971 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCaption()
973 ensureAlive();
974 return nullptr;
977 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleSummary()
979 ensureAlive();
980 return nullptr;
983 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 nColumn )
985 return isAccessibleColumnSelected( nColumn );
988 sal_Int64 SAL_CALL ScAccessibleCsvGrid::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
990 SolarMutexGuard aGuard;
991 ensureAlive();
992 ensureValidPosition( nRow, nColumn );
993 return implGetIndex( nRow, nColumn );
996 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRow( sal_Int64 nChildIndex )
998 SolarMutexGuard aGuard;
999 ensureAlive();
1000 ensureValidIndex( nChildIndex );
1001 return implGetRow( nChildIndex );
1004 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumn( sal_Int64 nChildIndex )
1006 SolarMutexGuard aGuard;
1007 ensureAlive();
1008 ensureValidIndex( nChildIndex );
1009 return implGetColumn( nChildIndex );
1012 // XAccessibleSelection -------------------------------------------------------
1014 void SAL_CALL ScAccessibleCsvGrid::selectAccessibleChild( sal_Int64 nChildIndex )
1016 SolarMutexGuard aGuard;
1017 ensureAlive();
1018 ensureValidIndex( nChildIndex );
1019 sal_Int32 nColumn = implGetColumn( nChildIndex );
1020 if( nChildIndex == 0 )
1021 implGetGrid().SelectAll();
1022 else
1023 implSelectColumn( nColumn, true );
1026 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleChildSelected( sal_Int64 nChildIndex )
1028 SolarMutexGuard aGuard;
1029 ensureAlive();
1030 ensureValidIndex( nChildIndex );
1031 sal_Int32 nColumn = implGetColumn( nChildIndex );
1032 return implIsColumnSelected( nColumn );
1035 void SAL_CALL ScAccessibleCsvGrid::clearAccessibleSelection()
1037 SolarMutexGuard aGuard;
1038 ensureAlive();
1039 implGetGrid().SelectAll( false );
1042 void SAL_CALL ScAccessibleCsvGrid::selectAllAccessibleChildren()
1044 selectAccessibleChild( 0 );
1047 sal_Int64 SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChildCount()
1049 SolarMutexGuard aGuard;
1050 ensureAlive();
1051 return static_cast<sal_Int64>(implGetRowCount()) * static_cast<sal_Int64>(implGetSelColumnCount());
1054 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex )
1056 SolarMutexGuard aGuard;
1057 ensureAlive();
1058 sal_Int32 nColumns = implGetSelColumnCount();
1059 if( nColumns == 0 )
1060 throw IndexOutOfBoundsException();
1062 sal_Int32 nRow = nSelectedChildIndex / nColumns;
1063 sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns );
1064 return getAccessibleCellAt( nRow, nColumn );
1067 void SAL_CALL ScAccessibleCsvGrid::deselectAccessibleChild( sal_Int64 nSelectedChildIndex )
1069 SolarMutexGuard aGuard;
1070 ensureAlive();
1071 ensureValidIndex(nSelectedChildIndex);
1072 sal_Int32 nColumns = implGetSelColumnCount();
1073 if( nColumns == 0 )
1074 throw IndexOutOfBoundsException();
1076 sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns );
1077 ensureValidPosition( nSelectedChildIndex / nColumns, nColumn );
1078 if( nColumn > 0 )
1079 implSelectColumn( nColumn, false );
1082 // events ---------------------------------------------------------------------
1084 void ScAccessibleCsvGrid::SendFocusEvent( bool bFocused )
1086 ScAccessibleCsvControl::SendFocusEvent( bFocused );
1087 Any aOldAny, aNewAny;
1088 (bFocused ? aNewAny : aOldAny) <<=
1089 getAccessibleCellAt( 0, lcl_GetApiColumn( implGetGrid().GetFocusColumn() ) );
1090 NotifyAccessibleEvent(AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldAny, aNewAny);
1093 void ScAccessibleCsvGrid::SendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows )
1095 if( nFirstColumn <= nLastColumn )
1097 AccessibleTableModelChange aModelChange(
1098 AccessibleTableModelChangeType::UPDATE, 0, bAllRows ? implGetRowCount() - 1 : 0,
1099 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1100 Any aOldAny, aNewAny;
1101 aNewAny <<= aModelChange;
1102 NotifyAccessibleEvent(AccessibleEventId::TABLE_MODEL_CHANGED, aOldAny, aNewAny);
1106 void ScAccessibleCsvGrid::SendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
1108 if( nFirstColumn <= nLastColumn )
1110 AccessibleTableModelChange aModelChange(
1111 AccessibleTableModelChangeType::COLUMNS_INSERTED, -1, -1,
1112 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1113 Any aOldAny, aNewAny;
1114 aNewAny <<= aModelChange;
1115 NotifyAccessibleEvent(AccessibleEventId::TABLE_MODEL_CHANGED, aOldAny, aNewAny);
1119 void ScAccessibleCsvGrid::SendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
1121 if( nFirstColumn <= nLastColumn )
1123 AccessibleTableModelChange aModelChange(
1124 AccessibleTableModelChangeType::COLUMNS_REMOVED, -1, -1,
1125 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1126 Any aOldAny, aNewAny;
1127 aNewAny <<= aModelChange;
1128 NotifyAccessibleEvent(AccessibleEventId::TABLE_MODEL_CHANGED, aOldAny, aNewAny);
1132 // helpers --------------------------------------------------------------------
1134 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleName()
1136 return ScResId( STR_ACC_CSVGRID_NAME );
1139 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleDescription()
1141 return ScResId( STR_ACC_CSVGRID_DESCR );
1144 void ScAccessibleCsvGrid::ensureValidIndex( sal_Int64 nIndex ) const
1146 if( (nIndex < 0) || (nIndex >= implGetCellCount()) )
1147 throw IndexOutOfBoundsException();
1150 void ScAccessibleCsvGrid::ensureValidPosition( sal_Int32 nRow, sal_Int32 nColumn ) const
1152 if( (nRow < 0) || (nRow >= implGetRowCount()) || (nColumn < 0) || (nColumn >= implGetColumnCount()) )
1153 throw IndexOutOfBoundsException();
1156 ScCsvGrid& ScAccessibleCsvGrid::implGetGrid() const
1158 return static_cast< ScCsvGrid& >( implGetControl() );
1161 bool ScAccessibleCsvGrid::implIsColumnSelected( sal_Int32 nColumn ) const
1163 return (nColumn > 0) && implGetGrid().IsSelected( lcl_GetGridColumn( nColumn ) );
1166 void ScAccessibleCsvGrid::implSelectColumn( sal_Int32 nColumn, bool bSelect )
1168 if( nColumn > 0 )
1169 implGetGrid().Select( lcl_GetGridColumn( nColumn ), bSelect );
1172 sal_Int32 ScAccessibleCsvGrid::implGetRowCount() const
1174 return static_cast< sal_Int32 >( implGetGrid().GetLastVisLine() - implGetGrid().GetFirstVisLine() + 2 );
1177 sal_Int32 ScAccessibleCsvGrid::implGetColumnCount() const
1179 return static_cast< sal_Int32 >( implGetGrid().GetColumnCount() + 1 );
1182 sal_Int32 ScAccessibleCsvGrid::implGetSelColumnCount() const
1184 ScCsvGrid& rGrid = implGetGrid();
1185 sal_Int32 nCount = 0;
1186 for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) )
1187 ++nCount;
1188 return nCount;
1191 sal_Int32 ScAccessibleCsvGrid::implGetSelColumn( sal_Int32 nSelColumn ) const
1193 ScCsvGrid& rGrid = implGetGrid();
1194 sal_Int32 nColumn = 0;
1195 for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) )
1197 if( nColumn == nSelColumn )
1198 return static_cast< sal_Int32 >( nColIx + 1 );
1199 ++nColumn;
1201 return 0;
1204 OUString ScAccessibleCsvGrid::implGetCellText( sal_Int32 nRow, sal_Int32 nColumn ) const
1206 ScCsvGrid& rGrid = implGetGrid();
1207 sal_Int32 nLine = nRow + rGrid.GetFirstVisLine() - 1;
1208 OUString aCellStr;
1209 if( (nColumn > 0) && (nRow > 0) )
1210 aCellStr = rGrid.GetCellText( lcl_GetGridColumn( nColumn ), nLine );
1211 else if( nRow > 0 )
1212 aCellStr = OUString::number( nLine + 1 );
1213 else if( nColumn > 0 )
1214 aCellStr = rGrid.GetColumnTypeName( lcl_GetGridColumn( nColumn ) );
1215 return aCellStr;
1218 rtl::Reference<ScAccessibleCsvCell> ScAccessibleCsvGrid::implCreateCellObj( sal_Int32 nRow, sal_Int32 nColumn )
1220 return new ScAccessibleCsvCell(implGetGrid(), implGetCellText(nRow, nColumn), nRow, nColumn);
1223 css::uno::Reference<css::accessibility::XAccessible> SAL_CALL ScAccessibleCsvGrid::getAccessibleParent()
1225 return implGetControl().GetDrawingArea()->get_accessible_parent();
1228 ScAccessibleCsvCell::ScAccessibleCsvCell(
1229 ScCsvGrid& rGrid,
1230 OUString aCellText,
1231 sal_Int32 nRow, sal_Int32 nColumn ) :
1232 ImplInheritanceHelper( rGrid ),
1233 AccessibleStaticTextBase( SvxEditSourcePtr() ),
1234 maCellText(std::move( aCellText )),
1235 mnLine( nRow ? (nRow + rGrid.GetFirstVisLine() - 1) : CSV_LINE_HEADER ),
1236 mnColumn( lcl_GetGridColumn( nColumn ) ),
1237 mnIndex( nRow * (rGrid.GetColumnCount() + 1) + nColumn )
1239 SetEditSource( implCreateEditSource() );
1242 ScAccessibleCsvCell::~ScAccessibleCsvCell()
1246 void SAL_CALL ScAccessibleCsvCell::disposing()
1248 SolarMutexGuard aGuard;
1249 SetEditSource( SvxEditSourcePtr() );
1250 ScAccessibleCsvControl::disposing();
1253 // XAccessibleComponent -------------------------------------------------------
1255 void SAL_CALL ScAccessibleCsvCell::grabFocus()
1257 SolarMutexGuard aGuard;
1258 ensureAlive();
1259 ScCsvGrid& rGrid = implGetGrid();
1260 rGrid.Execute( CSVCMD_MOVEGRIDCURSOR, rGrid.GetColumnPos( mnColumn ) );
1263 sal_Int32 SAL_CALL ScAccessibleCsvCell::getForeground( )
1265 SolarMutexGuard aGuard;
1266 ensureAlive();
1267 return sal_Int32(Application::GetSettings().GetStyleSettings().GetButtonTextColor());
1270 sal_Int32 SAL_CALL ScAccessibleCsvCell::getBackground( )
1272 SolarMutexGuard aGuard;
1273 ensureAlive();
1274 return sal_Int32(ScModule::get()->GetColorConfig().GetColorValue(::svtools::DOCCOLOR).nColor);
1277 // XAccessibleContext -----------------------------------------------------
1279 sal_Int64 SAL_CALL ScAccessibleCsvCell::getAccessibleChildCount()
1281 return AccessibleStaticTextBase::getAccessibleChildCount();
1284 Reference< XAccessible > SAL_CALL ScAccessibleCsvCell::getAccessibleChild( sal_Int64 nIndex )
1286 return AccessibleStaticTextBase::getAccessibleChild( nIndex );
1289 sal_Int64 SAL_CALL ScAccessibleCsvCell::getAccessibleIndexInParent()
1291 SolarMutexGuard aGuard;
1292 ensureAlive();
1293 return mnIndex;
1296 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvCell::getAccessibleRelationSet()
1298 SolarMutexGuard aGuard;
1299 ensureAlive();
1300 return new AccessibleRelationSetHelper();
1303 sal_Int64 SAL_CALL ScAccessibleCsvCell::getAccessibleStateSet()
1305 SolarMutexGuard aGuard;
1306 sal_Int64 nStateSet = implCreateStateSet();
1307 if( isAlive() )
1309 const ScCsvGrid& rGrid = implGetGrid();
1310 nStateSet |= AccessibleStateType::SINGLE_LINE;
1311 if( mnColumn != CSV_COLUMN_HEADER )
1312 nStateSet |= AccessibleStateType::SELECTABLE;
1313 if( rGrid.HasFocus() && (rGrid.GetFocusColumn() == mnColumn) && (mnLine == CSV_LINE_HEADER) )
1314 nStateSet |= AccessibleStateType::ACTIVE;
1315 if( rGrid.IsSelected( mnColumn ) )
1316 nStateSet |= AccessibleStateType::SELECTED;
1318 return nStateSet;
1321 // XInterface -----------------------------------------------------------------
1323 IMPLEMENT_FORWARD_XINTERFACE2( ScAccessibleCsvCell, ImplInheritanceHelper, AccessibleStaticTextBase )
1325 // XTypeProvider --------------------------------------------------------------
1327 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScAccessibleCsvCell, ImplInheritanceHelper, AccessibleStaticTextBase )
1329 // helpers --------------------------------------------------------------------
1331 OUString SAL_CALL ScAccessibleCsvCell::getAccessibleName()
1333 return maCellText;
1336 OUString SAL_CALL ScAccessibleCsvCell::getAccessibleDescription()
1338 return OUString();
1341 ScCsvGrid& ScAccessibleCsvCell::implGetGrid() const
1343 return static_cast< ScCsvGrid& >( implGetControl() );
1346 Point ScAccessibleCsvCell::implGetRealPos() const
1348 ScCsvGrid& rGrid = implGetGrid();
1349 return Point(
1350 (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrX() : rGrid.GetColumnX( mnColumn ),
1351 (mnLine == CSV_LINE_HEADER) ? 0 : rGrid.GetY( mnLine ) );
1354 sal_uInt32 ScAccessibleCsvCell::implCalcPixelWidth(sal_uInt32 nChars) const
1356 ScCsvGrid& rGrid = implGetGrid();
1357 return rGrid.GetCharWidth() * nChars;
1360 Size ScAccessibleCsvCell::implGetRealSize() const
1362 ScCsvGrid& rGrid = implGetGrid();
1363 return Size(
1364 (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrWidth() : implCalcPixelWidth( rGrid.GetColumnWidth( mnColumn ) ),
1365 (mnLine == CSV_LINE_HEADER) ? rGrid.GetHdrHeight() : rGrid.GetLineHeight() );
1368 css::awt::Rectangle ScAccessibleCsvCell::implGetBounds()
1370 ScCsvGrid& rGrid = implGetGrid();
1371 tools::Rectangle aClipRect( Point( 0, 0 ), rGrid.GetOutputSizePixel() );
1372 if( mnColumn != CSV_COLUMN_HEADER )
1374 aClipRect.SetLeft( rGrid.GetFirstX() );
1375 aClipRect.SetRight( rGrid.GetLastX() );
1377 if( mnLine != CSV_LINE_HEADER )
1378 aClipRect.SetTop( rGrid.GetHdrHeight() );
1380 tools::Rectangle aRect( implGetRealPos(), implGetRealSize() );
1381 aRect.Intersection( aClipRect );
1382 if( aRect.IsEmpty() )
1383 aRect.SetSize( Size( -1, -1 ) );
1385 return css::awt::Rectangle(aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight());
1388 ::std::unique_ptr< SvxEditSource > ScAccessibleCsvCell::implCreateEditSource()
1390 ScCsvGrid& rGrid = implGetGrid();
1392 ::std::unique_ptr< SvxEditSource > pEditSource( new ScAccessibilityEditSource( std::make_unique<ScAccessibleCsvTextData>(&rGrid.GetDrawingArea()->get_ref_device(), rGrid.GetEditEngine(), maCellText, implGetRealSize()) ) );
1393 return pEditSource;
1396 css::uno::Reference<css::accessibility::XAccessible> SAL_CALL ScAccessibleCsvCell::getAccessibleParent()
1398 ScCsvGrid& rGrid = implGetGrid();
1400 ScAccessibleCsvGrid* pAcc = static_cast<ScAccessibleCsvGrid*>(rGrid.GetAccessible());
1402 return pAcc;
1405 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */