calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / sc / source / ui / Accessibility / AccessibleCsvControl.cxx
blob9d7e2bab57990aa0897e15037eb44828a04ba595
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>
52 using ::utl::AccessibleRelationSetHelper;
53 using ::accessibility::AccessibleStaticTextBase;
54 using ::com::sun::star::uno::Any;
55 using ::com::sun::star::uno::Reference;
56 using ::com::sun::star::uno::Sequence;
57 using ::com::sun::star::uno::RuntimeException;
58 using ::com::sun::star::uno::XInterface;
59 using ::com::sun::star::lang::IndexOutOfBoundsException;
60 using ::com::sun::star::beans::PropertyValue;
61 using namespace ::com::sun::star::accessibility;
63 const sal_Unicode cRulerDot = '.';
64 const sal_Unicode cRulerLine = '|';
66 const sal_Int32 CSV_LINE_HEADER = CSV_POS_INVALID;
67 const sal_uInt32 CSV_COLUMN_HEADER = CSV_COLUMN_INVALID;
69 ScAccessibleCsvControl::ScAccessibleCsvControl(ScCsvControl& rControl)
70 : mpControl(&rControl)
74 ScAccessibleCsvControl::~ScAccessibleCsvControl()
76 ensureDisposed();
79 void SAL_CALL ScAccessibleCsvControl::disposing()
81 SolarMutexGuard aGuard;
82 mpControl = nullptr;
83 comphelper::OAccessibleComponentHelper::disposing();
86 // XAccessibleComponent -------------------------------------------------------
88 Reference< XAccessible > SAL_CALL ScAccessibleCsvControl::getAccessibleAtPoint( const css::awt::Point& /* rPoint */ )
90 ensureAlive();
91 return nullptr;
94 void SAL_CALL ScAccessibleCsvControl::grabFocus()
96 SolarMutexGuard aGuard;
97 ensureAlive();
98 implGetControl().GrabFocus();
101 // events ---------------------------------------------------------------------
103 void ScAccessibleCsvControl::SendFocusEvent( bool bFocused )
105 Any aOldAny, aNewAny;
106 if (bFocused)
107 aNewAny <<= AccessibleStateType::FOCUSED;
108 else
109 aOldAny <<= AccessibleStateType::FOCUSED;
110 NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny);
113 void ScAccessibleCsvControl::SendCaretEvent()
115 OSL_FAIL( "ScAccessibleCsvControl::SendCaretEvent - Illegal call" );
118 void ScAccessibleCsvControl::SendVisibleEvent()
120 NotifyAccessibleEvent(AccessibleEventId::VISIBLE_DATA_CHANGED, Any(), Any());
123 void ScAccessibleCsvControl::SendSelectionEvent()
125 NotifyAccessibleEvent(AccessibleEventId::SELECTION_CHANGED, Any(), Any());
128 void ScAccessibleCsvControl::SendTableUpdateEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */, bool /* bAllRows */ )
130 OSL_FAIL( "ScAccessibleCsvControl::SendTableUpdateEvent - Illegal call" );
133 void ScAccessibleCsvControl::SendInsertColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ )
135 OSL_FAIL( "ScAccessibleCsvControl::SendInsertColumnEvent - Illegal call" );
138 void ScAccessibleCsvControl::SendRemoveColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ )
140 OSL_FAIL( "ScAccessibleCsvControl::SendRemoveColumnEvent - Illegal call" );
143 // helpers --------------------------------------------------------------------
145 css::awt::Rectangle ScAccessibleCsvControl::implGetBounds()
147 SolarMutexGuard aGuard;
148 ensureAlive();
149 Size aOutSize(implGetControl().GetOutputSizePixel());
150 return css::awt::Rectangle(0, 0, aOutSize.Width(), aOutSize.Height());
153 ScCsvControl& ScAccessibleCsvControl::implGetControl() const
155 assert(mpControl && "ScAccessibleCsvControl::implGetControl - missing control");
156 return *mpControl;
159 sal_Int64 ScAccessibleCsvControl::implCreateStateSet()
161 SolarMutexGuard aGuard;
162 sal_Int64 nStateSet = 0;
163 if (isAlive())
165 const ScCsvControl& rCtrl = implGetControl();
166 nStateSet |= AccessibleStateType::OPAQUE;
167 if( rCtrl.IsEnabled() )
168 nStateSet |= AccessibleStateType::ENABLED;
169 if( rCtrl.IsReallyVisible() )
170 nStateSet |= AccessibleStateType::SHOWING;
171 if( rCtrl.IsVisible() )
172 nStateSet |= AccessibleStateType::VISIBLE;
174 else
175 nStateSet |= AccessibleStateType::DEFUNC;
176 return nStateSet;
179 // Ruler ======================================================================
181 /** Converts a ruler cursor position to API text index. */
182 static sal_Int32 lcl_GetApiPos( sal_Int32 nRulerPos )
184 sal_Int32 nApiPos = nRulerPos;
185 sal_Int32 nStart = (nRulerPos - 1) / 10;
186 sal_Int32 nExp = 1;
187 while( nStart >= nExp )
189 nApiPos += nStart - nExp + 1;
190 nExp *= 10;
192 return ::std::max( nApiPos, static_cast<sal_Int32>(0) );
195 /** Converts an API text index to a ruler cursor position. */
196 static sal_Int32 lcl_GetRulerPos( sal_Int32 nApiPos )
198 sal_Int32 nDiv = 10;
199 sal_Int32 nExp = 10;
200 sal_Int32 nRulerPos = 0;
201 sal_Int32 nApiBase = 0;
202 sal_Int32 nApiLimit = 10;
203 while( nApiPos >= nApiLimit )
205 ++nDiv;
206 nRulerPos = nExp;
207 nExp *= 10;
208 nApiBase = nApiLimit;
209 nApiLimit = lcl_GetApiPos( nExp );
211 sal_Int32 nRelPos = nApiPos - nApiBase;
212 return nRulerPos + nRelPos / nDiv * 10 + ::std::max<sal_Int32>( nRelPos % nDiv - nDiv + 10, 0 );
215 /** Expands the sequence's size and returns the base index of the new inserted elements. */
216 static sal_Int32 lcl_ExpandSequence( Sequence< PropertyValue >& rSeq, sal_Int32 nExp )
218 OSL_ENSURE( nExp > 0, "lcl_ExpandSequence - invalid value" );
219 rSeq.realloc( rSeq.getLength() + nExp );
220 return rSeq.getLength() - nExp;
223 /** Fills the property value rVal with the specified name and value from the item. */
224 static void lcl_FillProperty( PropertyValue& rVal, const OUString& rPropName, const SfxPoolItem& rItem, sal_uInt8 nMID )
226 rVal.Name = rPropName;
227 rItem.QueryValue( rVal.Value, nMID );
230 /** Fills the sequence with all font attributes of rFont. */
231 static void lcl_FillFontAttributes( Sequence< PropertyValue >& rSeq, const vcl::Font& rFont )
233 SvxFontItem aFontItem( rFont.GetFamilyType(), rFont.GetFamilyName(), rFont.GetStyleName(), rFont.GetPitch(), rFont.GetCharSet(), ATTR_FONT );
234 SvxFontHeightItem aHeightItem( rFont.GetFontSize().Height(), 100, ATTR_FONT_HEIGHT );
235 SvxLanguageItem aLangItem( rFont.GetLanguage(), ATTR_FONT_LANGUAGE );
237 sal_Int32 nIndex = lcl_ExpandSequence( rSeq, 7 );
238 auto pSeq = rSeq.getArray();
239 lcl_FillProperty( pSeq[ nIndex++ ], "CharFontName", aFontItem, MID_FONT_FAMILY_NAME );
240 lcl_FillProperty( pSeq[ nIndex++ ], "CharFontFamily", aFontItem, MID_FONT_FAMILY );
241 lcl_FillProperty( pSeq[ nIndex++ ], "CharFontStyleName", aFontItem, MID_FONT_STYLE_NAME );
242 lcl_FillProperty( pSeq[ nIndex++ ], "CharFontCharSet", aFontItem, MID_FONT_PITCH );
243 lcl_FillProperty( pSeq[ nIndex++ ], "CharFontPitch", aFontItem, MID_FONT_CHAR_SET );
244 lcl_FillProperty( pSeq[ nIndex++ ], "CharHeight", aHeightItem, MID_FONTHEIGHT );
245 lcl_FillProperty( pSeq[ nIndex++ ], "CharLocale", aLangItem, MID_LANG_LOCALE );
248 ScAccessibleCsvRuler::ScAccessibleCsvRuler(ScCsvRuler& rRuler)
249 : ScAccessibleCsvControl(rRuler)
251 constructStringBuffer();
254 ScAccessibleCsvRuler::~ScAccessibleCsvRuler()
256 ensureDisposed();
259 // XAccessibleComponent -----------------------------------------------------
261 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getForeground( )
263 SolarMutexGuard aGuard;
264 ensureAlive();
265 return sal_Int32(Application::GetSettings().GetStyleSettings().GetLabelTextColor());
268 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getBackground( )
270 SolarMutexGuard aGuard;
271 ensureAlive();
272 return sal_Int32(Application::GetSettings().GetStyleSettings().GetFaceColor());
275 // XAccessibleContext ---------------------------------------------------------
277 sal_Int64 SAL_CALL ScAccessibleCsvRuler::getAccessibleChildCount()
279 ensureAlive();
280 return 0;
283 Reference< XAccessible > SAL_CALL ScAccessibleCsvRuler::getAccessibleChild( sal_Int64 /* nIndex */ )
285 ensureAlive();
286 throw IndexOutOfBoundsException();
289 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvRuler::getAccessibleRelationSet()
291 SolarMutexGuard aGuard;
292 ensureAlive();
293 rtl::Reference<AccessibleRelationSetHelper> pRelationSet = new AccessibleRelationSetHelper();
295 ScCsvRuler& rRuler = implGetRuler();
296 ScCsvTableBox* pTableBox = rRuler.GetTableBox();
297 ScCsvGrid& rGrid = pTableBox->GetGrid();
299 css::uno::Reference<css::accessibility::XAccessible> xAccObj(static_cast<ScAccessibleCsvGrid*>(rGrid.GetAccessible()));
300 if( xAccObj.is() )
302 Sequence< Reference< XInterface > > aSeq{ xAccObj };
303 pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::CONTROLLER_FOR, aSeq ) );
306 return pRelationSet;
309 sal_Int64 SAL_CALL ScAccessibleCsvRuler::getAccessibleStateSet()
311 SolarMutexGuard aGuard;
312 sal_Int64 nStateSet = implCreateStateSet();
313 if( isAlive() )
315 nStateSet |= AccessibleStateType::FOCUSABLE;
316 nStateSet |= AccessibleStateType::SINGLE_LINE;
317 if( implGetRuler().HasFocus() )
318 nStateSet |= AccessibleStateType::FOCUSED;
320 return nStateSet;
323 // XAccessibleText ------------------------------------------------------------
325 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCaretPosition()
327 SolarMutexGuard aGuard;
328 ensureAlive();
329 return lcl_GetApiPos( implGetRuler().GetRulerCursorPos() );
332 sal_Bool SAL_CALL ScAccessibleCsvRuler::setCaretPosition( sal_Int32 nIndex )
334 SolarMutexGuard aGuard;
335 ensureAlive();
336 ensureValidIndex( nIndex );
337 ScCsvRuler& rRuler = implGetRuler();
338 sal_Int32 nOldCursor = rRuler.GetRulerCursorPos();
339 rRuler.Execute( CSVCMD_MOVERULERCURSOR, lcl_GetRulerPos( nIndex ) );
340 return rRuler.GetRulerCursorPos() != nOldCursor;
343 sal_Unicode SAL_CALL ScAccessibleCsvRuler::getCharacter( sal_Int32 nIndex )
345 SolarMutexGuard aGuard;
346 ensureAlive();
347 ensureValidIndex( nIndex );
348 return maBuffer[nIndex];
351 Sequence< PropertyValue > SAL_CALL ScAccessibleCsvRuler::getCharacterAttributes( sal_Int32 nIndex,
352 const css::uno::Sequence< OUString >& /* aRequestedAttributes */ )
354 SolarMutexGuard aGuard;
355 ensureAlive();
356 ensureValidIndexWithEnd( nIndex );
357 Sequence< PropertyValue > aSeq;
358 lcl_FillFontAttributes( aSeq, implGetRuler().GetDrawingArea()->get_ref_device().GetFont() );
359 return aSeq;
362 css::awt::Rectangle SAL_CALL ScAccessibleCsvRuler::getCharacterBounds( sal_Int32 nIndex )
364 SolarMutexGuard aGuard;
365 ensureAlive();
366 ensureValidIndexWithEnd( nIndex );
367 ScCsvRuler& rRuler = implGetRuler();
368 Point aPos( rRuler.GetX( lcl_GetRulerPos( nIndex ) ) - rRuler.GetCharWidth() / 2, 0 );
369 css::awt::Rectangle aRect( aPos.X(), aPos.Y(), rRuler.GetCharWidth(), rRuler.GetOutputSizePixel().Height() );
370 // do not return rectangle out of window
371 sal_Int32 nWidth = rRuler.GetOutputSizePixel().Width();
372 if( aRect.X >= nWidth )
373 throw IndexOutOfBoundsException();
374 if( aRect.X + aRect.Width > nWidth )
375 aRect.Width = nWidth - aRect.X;
376 return aRect;
379 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCharacterCount()
381 SolarMutexGuard aGuard;
382 ensureAlive();
383 return implGetTextLength();
386 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getIndexAtPoint( const css::awt::Point& rPoint )
388 SolarMutexGuard aGuard;
389 ensureAlive();
390 ScCsvRuler& rRuler = implGetRuler();
391 // use object's coordinate system, convert to API position
392 return lcl_GetApiPos( ::std::clamp( rRuler.GetPosFromX( rPoint.X ), sal_Int32(0), rRuler.GetPosCount() ) );
395 OUString SAL_CALL ScAccessibleCsvRuler::getSelectedText()
397 ensureAlive();
398 return OUString();
401 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionStart()
403 ensureAlive();
404 return -1;
407 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionEnd()
409 ensureAlive();
410 return -1;
413 sal_Bool SAL_CALL ScAccessibleCsvRuler::setSelection( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ )
415 ensureAlive();
416 return false;
419 OUString SAL_CALL ScAccessibleCsvRuler::getText()
421 SolarMutexGuard aGuard;
422 ensureAlive();
423 return OUString( maBuffer.getStr(), implGetTextLength() );
426 OUString SAL_CALL ScAccessibleCsvRuler::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
428 SolarMutexGuard aGuard;
429 ensureAlive();
430 ensureValidRange( nStartIndex, nEndIndex );
431 return OUString( maBuffer.getStr() + nStartIndex, nEndIndex - nStartIndex );
434 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextAtIndex( sal_Int32 nIndex, sal_Int16 nTextType )
436 SolarMutexGuard aGuard;
437 ensureAlive();
439 TextSegment aResult;
440 aResult.SegmentStart = -1;
441 aResult.SegmentEnd = -1;
443 if( (nIndex == implGetTextLength()) && (nTextType != AccessibleTextType::LINE) )
444 return aResult;
446 ensureValidIndex( nIndex );
448 OUStringBuffer aResultText; // will be assigned to aResult.SegmentText below
449 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
451 switch( nTextType )
453 // single character
454 case AccessibleTextType::CHARACTER:
456 aResult.SegmentStart = nIndex;
457 aResultText.append(maBuffer[nIndex]);
459 break;
461 // entire number or single dot/line
462 case AccessibleTextType::WORD:
463 case AccessibleTextType::GLYPH:
464 aResult.SegmentStart = nIndex;
465 if( nRulerPos % 10 )
466 aResultText.append(maBuffer[nIndex]);
467 else
468 aResultText.append( nRulerPos ); // string representation of sal_Int32!!!
469 break;
471 // entire text
472 case AccessibleTextType::SENTENCE:
473 case AccessibleTextType::PARAGRAPH:
474 case AccessibleTextType::LINE:
475 aResult.SegmentStart = 0;
476 aResultText.append( maBuffer.getStr(), implGetTextLength() );
477 break;
479 // equal-formatted text
480 case AccessibleTextType::ATTRIBUTE_RUN:
482 sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex );
483 sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex );
484 aResult.SegmentStart = nFirstIndex;
485 aResultText.append( maBuffer.getStr() + nFirstIndex, nLastIndex - nFirstIndex + 1 );
487 break;
489 default:
490 throw RuntimeException();
493 aResult.SegmentText = aResultText.makeStringAndClear();
494 aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
495 return aResult;
498 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 nTextType )
500 SolarMutexGuard aGuard;
501 ensureAlive();
502 ensureValidIndexWithEnd( nIndex );
504 TextSegment aResult;
505 aResult.SegmentStart = -1;
506 aResult.SegmentEnd = -1;
508 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
510 switch( nTextType )
512 // single character
513 case AccessibleTextType::CHARACTER:
514 if( nIndex > 0 )
515 aResult = getTextAtIndex( nIndex - 1, nTextType );
516 // else empty
517 break;
519 // entire number or single dot/line
520 case AccessibleTextType::WORD:
521 case AccessibleTextType::GLYPH:
522 if( nRulerPos > 0 )
523 aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos - 1 ), nTextType );
524 // else empty
525 break;
527 // entire text
528 case AccessibleTextType::SENTENCE:
529 case AccessibleTextType::PARAGRAPH:
530 case AccessibleTextType::LINE:
531 // empty
532 break;
534 // equal-formatted text
535 case AccessibleTextType::ATTRIBUTE_RUN:
537 sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex );
538 if( nFirstIndex > 0 )
539 aResult = getTextAtIndex( nFirstIndex - 1, nTextType );
540 // else empty
542 break;
544 default:
545 throw RuntimeException();
547 return aResult;
550 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 nTextType )
552 SolarMutexGuard aGuard;
553 ensureAlive();
554 ensureValidIndexWithEnd( nIndex );
556 TextSegment aResult;
557 aResult.SegmentStart = -1;
558 aResult.SegmentEnd = -1;
560 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
561 sal_Int32 nLastValid = implGetTextLength();
563 switch( nTextType )
565 // single character
566 case AccessibleTextType::CHARACTER:
567 if( nIndex < nLastValid )
568 aResult = getTextAtIndex( nIndex + 1, nTextType );
569 // else empty
570 break;
572 // entire number or single dot/line
573 case AccessibleTextType::WORD:
574 case AccessibleTextType::GLYPH:
575 if( nRulerPos < implGetRuler().GetPosCount() )
576 aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos + 1 ), nTextType );
577 // else empty
578 break;
580 // entire text
581 case AccessibleTextType::SENTENCE:
582 case AccessibleTextType::PARAGRAPH:
583 case AccessibleTextType::LINE:
584 // empty
585 break;
587 // equal-formatted text
588 case AccessibleTextType::ATTRIBUTE_RUN:
590 sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex );
591 if( nLastIndex < nLastValid )
592 aResult = getTextAtIndex( nLastIndex + 1, nTextType );
593 // else empty
595 break;
597 default:
598 throw RuntimeException();
600 return aResult;
603 sal_Bool SAL_CALL ScAccessibleCsvRuler::copyText( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ )
605 ensureAlive();
606 return false;
609 sal_Bool SAL_CALL ScAccessibleCsvRuler::scrollSubstringTo( sal_Int32 /* nStartIndex */, sal_Int32/* nEndIndex */, AccessibleScrollType /* aScrollType */ )
611 return false;
614 // XInterface -----------------------------------------------------------------
616 Any SAL_CALL ScAccessibleCsvRuler::queryInterface( const css::uno::Type& rType )
618 Any aAny( ScAccessibleCsvRulerImpl::queryInterface( rType ) );
619 return aAny.hasValue() ? aAny : ScAccessibleCsvControl::queryInterface( rType );
622 void SAL_CALL ScAccessibleCsvRuler::acquire() noexcept
624 ScAccessibleCsvControl::acquire();
627 void SAL_CALL ScAccessibleCsvRuler::release() noexcept
629 ScAccessibleCsvControl::release();
632 // XTypeProvider --------------------------------------------------------------
634 Sequence< css::uno::Type > SAL_CALL ScAccessibleCsvRuler::getTypes()
636 return ::comphelper::concatSequences( ScAccessibleCsvControl::getTypes(),
637 Sequence { cppu::UnoType<XAccessibleText>::get() });
640 Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvRuler::getImplementationId()
642 return css::uno::Sequence<sal_Int8>();
645 // events ---------------------------------------------------------------------
647 void ScAccessibleCsvRuler::SendCaretEvent()
649 sal_Int32 nPos = implGetRuler().GetRulerCursorPos();
650 if (nPos != CSV_POS_INVALID)
652 Any aOldValue, aNewValue;
653 aNewValue <<= nPos;
654 NotifyAccessibleEvent( AccessibleEventId::CARET_CHANGED, aOldValue, aNewValue );
658 // helpers --------------------------------------------------------------------
660 OUString SAL_CALL ScAccessibleCsvRuler::getAccessibleName()
662 return ScResId( STR_ACC_CSVRULER_NAME );
665 OUString SAL_CALL ScAccessibleCsvRuler::getAccessibleDescription()
667 return ScResId( STR_ACC_CSVRULER_DESCR );
670 void ScAccessibleCsvRuler::ensureValidIndex( sal_Int32 nIndex ) const
672 if( (nIndex < 0) || (nIndex >= implGetTextLength()) )
673 throw IndexOutOfBoundsException();
676 void ScAccessibleCsvRuler::ensureValidIndexWithEnd( sal_Int32 nIndex ) const
678 if( (nIndex < 0) || (nIndex > implGetTextLength()) )
679 throw IndexOutOfBoundsException();
682 void ScAccessibleCsvRuler::ensureValidRange( sal_Int32& rnStartIndex, sal_Int32& rnEndIndex ) const
684 if( rnStartIndex > rnEndIndex )
685 ::std::swap( rnStartIndex, rnEndIndex );
686 if( (rnStartIndex < 0) || (rnEndIndex > implGetTextLength()) )
687 throw IndexOutOfBoundsException();
690 ScCsvRuler& ScAccessibleCsvRuler::implGetRuler() const
692 return static_cast< ScCsvRuler& >( implGetControl() );
695 void ScAccessibleCsvRuler::constructStringBuffer()
697 SolarMutexGuard aGuard;
698 ensureAlive();
699 // extend existing string buffer to new ruler size
700 sal_Int32 nRulerCount = implGetRuler().GetPosCount();
701 sal_Int32 nRulerPos = lcl_GetRulerPos( maBuffer.getLength() );
702 for( ; nRulerPos <= nRulerCount; ++nRulerPos ) // include last position
704 switch( nRulerPos % 10 )
706 case 0: maBuffer.append( nRulerPos ); break;
707 case 5: maBuffer.append( cRulerLine ); break;
708 default: maBuffer.append( cRulerDot );
713 sal_Int32 ScAccessibleCsvRuler::implGetTextLength() const
715 return lcl_GetApiPos( implGetRuler().GetPosCount() + 1 );
718 bool ScAccessibleCsvRuler::implHasSplit( sal_Int32 nApiPos )
720 sal_Int32 nRulerPos = lcl_GetRulerPos( nApiPos );
721 return implGetRuler().HasSplit( nRulerPos ) && (nApiPos == lcl_GetApiPos( nRulerPos ));
724 sal_Int32 ScAccessibleCsvRuler::implGetFirstEqualFormatted( sal_Int32 nApiPos )
726 bool bSplit = implHasSplit( nApiPos );
727 while( (nApiPos > 0) && (implHasSplit( nApiPos - 1 ) == bSplit) )
728 --nApiPos;
729 return nApiPos;
732 sal_Int32 ScAccessibleCsvRuler::implGetLastEqualFormatted( sal_Int32 nApiPos )
734 bool bSplit = implHasSplit( nApiPos );
735 sal_Int32 nLength = implGetTextLength();
736 while( (nApiPos < nLength - 1) && (implHasSplit( nApiPos + 1 ) == bSplit) )
737 ++nApiPos;
738 return nApiPos;
741 css::uno::Reference<css::accessibility::XAccessible> SAL_CALL ScAccessibleCsvRuler::getAccessibleParent()
743 return implGetControl().GetDrawingArea()->get_accessible_parent();
746 // Grid =======================================================================
748 /** Converts a grid columnm index to an API column index. */
749 static sal_Int32 lcl_GetApiColumn( sal_uInt32 nGridColumn )
751 return (nGridColumn != CSV_COLUMN_HEADER) ? static_cast< sal_Int32 >( nGridColumn + 1 ) : 0;
754 /** Converts an API columnm index to a ScCsvGrid column index. */
755 static sal_uInt32 lcl_GetGridColumn( sal_Int32 nApiColumn )
757 return (nApiColumn > 0) ? static_cast< sal_uInt32 >( nApiColumn - 1 ) : CSV_COLUMN_HEADER;
760 ScAccessibleCsvGrid::ScAccessibleCsvGrid(ScCsvGrid& rGrid)
761 : ScAccessibleCsvControl(rGrid)
765 ScAccessibleCsvGrid::~ScAccessibleCsvGrid()
767 ensureDisposed();
770 void ScAccessibleCsvGrid::disposing()
772 SolarMutexGuard aGuard;
773 for (auto& rEntry : maAccessibleChildren)
774 rEntry.second->dispose();
775 maAccessibleChildren.clear();
776 ScAccessibleCsvControl::disposing();
779 // XAccessibleComponent -------------------------------------------------------
781 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleAtPoint( const css::awt::Point& rPoint )
783 Reference< XAccessible > xRet;
784 if( containsPoint( rPoint ) )
786 SolarMutexGuard aGuard;
787 ensureAlive();
789 const ScCsvGrid& rGrid = implGetGrid();
790 // #102679#; use <= instead of <, because the offset is the size and not the point
791 sal_Int32 nColumn = ((rGrid.GetFirstX() <= rPoint.X) && (rPoint.X <= rGrid.GetLastX())) ?
792 lcl_GetApiColumn( rGrid.GetColumnFromX( rPoint.X ) ) : 0;
793 sal_Int32 nRow = (rPoint.Y >= rGrid.GetHdrHeight()) ?
794 (rGrid.GetLineFromY( rPoint.Y ) - rGrid.GetFirstVisLine() + 1) : 0;
795 xRet = getAccessibleCell(nRow, nColumn);
797 return xRet;
800 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getForeground( )
802 SolarMutexGuard aGuard;
803 ensureAlive();
804 return sal_Int32(Application::GetSettings().GetStyleSettings().GetButtonTextColor());
807 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getBackground( )
809 SolarMutexGuard aGuard;
810 ensureAlive();
811 return sal_Int32(SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor);
814 // XAccessibleContext ---------------------------------------------------------
816 sal_Int64 SAL_CALL ScAccessibleCsvGrid::getAccessibleChildCount()
818 SolarMutexGuard aGuard;
819 ensureAlive();
820 return implGetCellCount();
823 Reference<XAccessible> ScAccessibleCsvGrid::getAccessibleCell(sal_Int32 nRow, sal_Int32 nColumn)
825 sal_Int64 nIndex = implGetIndex(nRow, nColumn);
827 XAccessibleSet::iterator aI = maAccessibleChildren.lower_bound(nIndex);
828 if (aI != maAccessibleChildren.end() && !(maAccessibleChildren.key_comp()(nIndex, aI->first)))
830 // key already exists
831 return aI->second;
833 // key does not exist
834 rtl::Reference<ScAccessibleCsvCell> xNew = implCreateCellObj(nRow, nColumn);
835 maAccessibleChildren.insert(aI, XAccessibleSet::value_type(nIndex, xNew));
836 return xNew;
839 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleChild( sal_Int64 nIndex )
841 SolarMutexGuard aGuard;
842 ensureAlive();
843 ensureValidIndex( nIndex );
845 return getAccessibleCell(implGetRow(nIndex), implGetColumn(nIndex));
848 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleRelationSet()
850 SolarMutexGuard aGuard;
851 ensureAlive();
852 rtl::Reference<AccessibleRelationSetHelper> pRelationSet = new AccessibleRelationSetHelper();
854 ScCsvGrid& rGrid = implGetGrid();
855 ScCsvTableBox* pTableBox = rGrid.GetTableBox();
856 ScCsvRuler& rRuler = pTableBox->GetRuler();
858 if (rRuler.IsVisible())
860 css::uno::Reference<css::accessibility::XAccessible> xAccObj(static_cast<ScAccessibleCsvGrid*>(rRuler.GetAccessible()));
861 if( xAccObj.is() )
863 Sequence< Reference< XInterface > > aSeq{ xAccObj };
864 pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::CONTROLLED_BY, aSeq ) );
868 return pRelationSet;
871 sal_Int64 SAL_CALL ScAccessibleCsvGrid::getAccessibleStateSet()
873 SolarMutexGuard aGuard;
874 sal_Int64 nStateSet = implCreateStateSet();
875 if( isAlive() )
877 nStateSet |= AccessibleStateType::FOCUSABLE;
878 nStateSet |= AccessibleStateType::MULTI_SELECTABLE;
879 nStateSet |= AccessibleStateType::MANAGES_DESCENDANTS;
880 if( implGetGrid().HasFocus() )
881 nStateSet |= AccessibleStateType::FOCUSED;
883 else
884 nStateSet |= AccessibleStateType::DEFUNC;
885 return nStateSet;
888 // XAccessibleTable -----------------------------------------------------------
890 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowCount()
892 SolarMutexGuard aGuard;
893 ensureAlive();
894 return implGetRowCount();
897 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnCount()
899 SolarMutexGuard aGuard;
900 ensureAlive();
901 return implGetColumnCount();
904 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleRowDescription( sal_Int32 nRow )
906 SolarMutexGuard aGuard;
907 ensureAlive();
908 ensureValidPosition( nRow, 0 );
909 return implGetCellText( nRow, 0 );
912 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnDescription( sal_Int32 nColumn )
914 SolarMutexGuard aGuard;
915 ensureAlive();
916 ensureValidPosition( 0, nColumn );
917 return implGetCellText( 0, nColumn );
920 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
922 ensureAlive();
923 ensureValidPosition( nRow, nColumn );
924 return 1;
927 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
929 ensureAlive();
930 ensureValidPosition( nRow, nColumn );
931 return 1;
934 Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleRowHeaders()
936 ensureAlive();
937 return nullptr;
940 Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnHeaders()
942 ensureAlive();
943 return nullptr;
946 Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleRows()
948 ensureAlive();
949 return Sequence< sal_Int32 >();
952 Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleColumns()
954 SolarMutexGuard aGuard;
955 ensureAlive();
957 ScCsvGrid& rGrid = implGetGrid();
958 Sequence< sal_Int32 > aSeq( implGetColumnCount() );
959 auto pSeq = aSeq.getArray();
961 sal_Int32 nSeqIx = 0;
962 sal_uInt32 nColIx = rGrid.GetFirstSelected();
963 for( ; nColIx != CSV_COLUMN_INVALID; ++nSeqIx, nColIx = rGrid.GetNextSelected( nColIx ) )
964 pSeq[ nSeqIx ] = lcl_GetApiColumn( nColIx );
966 aSeq.realloc( nSeqIx );
967 return aSeq;
970 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleRowSelected( sal_Int32 /* nRow */ )
972 ensureAlive();
973 return false;
976 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleColumnSelected( sal_Int32 nColumn )
978 SolarMutexGuard aGuard;
979 ensureAlive();
980 ensureValidIndex( nColumn );
981 return implIsColumnSelected( nColumn );
984 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
986 SolarMutexGuard aGuard;
987 ensureAlive();
988 ensureValidPosition( nRow, nColumn );
989 return getAccessibleCell(nRow, nColumn);
992 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCaption()
994 ensureAlive();
995 return nullptr;
998 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleSummary()
1000 ensureAlive();
1001 return nullptr;
1004 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 nColumn )
1006 return isAccessibleColumnSelected( nColumn );
1009 sal_Int64 SAL_CALL ScAccessibleCsvGrid::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
1011 SolarMutexGuard aGuard;
1012 ensureAlive();
1013 ensureValidPosition( nRow, nColumn );
1014 return implGetIndex( nRow, nColumn );
1017 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRow( sal_Int64 nChildIndex )
1019 SolarMutexGuard aGuard;
1020 ensureAlive();
1021 ensureValidIndex( nChildIndex );
1022 return implGetRow( nChildIndex );
1025 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumn( sal_Int64 nChildIndex )
1027 SolarMutexGuard aGuard;
1028 ensureAlive();
1029 ensureValidIndex( nChildIndex );
1030 return implGetColumn( nChildIndex );
1033 // XAccessibleSelection -------------------------------------------------------
1035 void SAL_CALL ScAccessibleCsvGrid::selectAccessibleChild( sal_Int64 nChildIndex )
1037 SolarMutexGuard aGuard;
1038 ensureAlive();
1039 ensureValidIndex( nChildIndex );
1040 sal_Int32 nColumn = implGetColumn( nChildIndex );
1041 if( nChildIndex == 0 )
1042 implGetGrid().SelectAll();
1043 else
1044 implSelectColumn( nColumn, true );
1047 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleChildSelected( sal_Int64 nChildIndex )
1049 SolarMutexGuard aGuard;
1050 ensureAlive();
1051 ensureValidIndex( nChildIndex );
1052 sal_Int32 nColumn = implGetColumn( nChildIndex );
1053 return implIsColumnSelected( nColumn );
1056 void SAL_CALL ScAccessibleCsvGrid::clearAccessibleSelection()
1058 SolarMutexGuard aGuard;
1059 ensureAlive();
1060 implGetGrid().SelectAll( false );
1063 void SAL_CALL ScAccessibleCsvGrid::selectAllAccessibleChildren()
1065 selectAccessibleChild( 0 );
1068 sal_Int64 SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChildCount()
1070 SolarMutexGuard aGuard;
1071 ensureAlive();
1072 return static_cast<sal_Int64>(implGetRowCount()) * static_cast<sal_Int64>(implGetSelColumnCount());
1075 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex )
1077 SolarMutexGuard aGuard;
1078 ensureAlive();
1079 sal_Int32 nColumns = implGetSelColumnCount();
1080 if( nColumns == 0 )
1081 throw IndexOutOfBoundsException();
1083 sal_Int32 nRow = nSelectedChildIndex / nColumns;
1084 sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns );
1085 return getAccessibleCellAt( nRow, nColumn );
1088 void SAL_CALL ScAccessibleCsvGrid::deselectAccessibleChild( sal_Int64 nSelectedChildIndex )
1090 SolarMutexGuard aGuard;
1091 ensureAlive();
1092 ensureValidIndex(nSelectedChildIndex);
1093 sal_Int32 nColumns = implGetSelColumnCount();
1094 if( nColumns == 0 )
1095 throw IndexOutOfBoundsException();
1097 sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns );
1098 ensureValidPosition( nSelectedChildIndex / nColumns, nColumn );
1099 if( nColumn > 0 )
1100 implSelectColumn( nColumn, false );
1103 // XInterface -----------------------------------------------------------------
1105 Any SAL_CALL ScAccessibleCsvGrid::queryInterface( const css::uno::Type& rType )
1107 Any aAny( ScAccessibleCsvGridImpl::queryInterface( rType ) );
1108 return aAny.hasValue() ? aAny : ScAccessibleCsvControl::queryInterface( rType );
1111 void SAL_CALL ScAccessibleCsvGrid::acquire() noexcept
1113 ScAccessibleCsvControl::acquire();
1116 void SAL_CALL ScAccessibleCsvGrid::release() noexcept
1118 ScAccessibleCsvControl::release();
1121 // XTypeProvider --------------------------------------------------------------
1123 Sequence< css::uno::Type > SAL_CALL ScAccessibleCsvGrid::getTypes()
1125 return ::comphelper::concatSequences( ScAccessibleCsvControl::getTypes(),
1126 Sequence {
1127 cppu::UnoType<XAccessibleTable>::get(),
1128 cppu::UnoType<XAccessibleSelection>::get() });
1131 Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvGrid::getImplementationId()
1133 return css::uno::Sequence<sal_Int8>();
1136 // events ---------------------------------------------------------------------
1138 void ScAccessibleCsvGrid::SendFocusEvent( bool bFocused )
1140 ScAccessibleCsvControl::SendFocusEvent( bFocused );
1141 Any aOldAny, aNewAny;
1142 (bFocused ? aNewAny : aOldAny) <<=
1143 getAccessibleCellAt( 0, lcl_GetApiColumn( implGetGrid().GetFocusColumn() ) );
1144 NotifyAccessibleEvent(AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldAny, aNewAny);
1147 void ScAccessibleCsvGrid::SendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows )
1149 if( nFirstColumn <= nLastColumn )
1151 AccessibleTableModelChange aModelChange(
1152 AccessibleTableModelChangeType::UPDATE, 0, bAllRows ? implGetRowCount() - 1 : 0,
1153 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1154 Any aOldAny, aNewAny;
1155 aNewAny <<= aModelChange;
1156 NotifyAccessibleEvent(AccessibleEventId::TABLE_MODEL_CHANGED, aOldAny, aNewAny);
1160 void ScAccessibleCsvGrid::SendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
1162 if( nFirstColumn <= nLastColumn )
1164 AccessibleTableModelChange aModelChange(
1165 AccessibleTableModelChangeType::COLUMNS_INSERTED, -1, -1,
1166 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1167 Any aOldAny, aNewAny;
1168 aNewAny <<= aModelChange;
1169 NotifyAccessibleEvent(AccessibleEventId::TABLE_MODEL_CHANGED, aOldAny, aNewAny);
1173 void ScAccessibleCsvGrid::SendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
1175 if( nFirstColumn <= nLastColumn )
1177 AccessibleTableModelChange aModelChange(
1178 AccessibleTableModelChangeType::COLUMNS_REMOVED, -1, -1,
1179 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1180 Any aOldAny, aNewAny;
1181 aNewAny <<= aModelChange;
1182 NotifyAccessibleEvent(AccessibleEventId::TABLE_MODEL_CHANGED, aOldAny, aNewAny);
1186 // helpers --------------------------------------------------------------------
1188 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleName()
1190 return ScResId( STR_ACC_CSVGRID_NAME );
1193 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleDescription()
1195 return ScResId( STR_ACC_CSVGRID_DESCR );
1198 void ScAccessibleCsvGrid::ensureValidIndex( sal_Int64 nIndex ) const
1200 if( (nIndex < 0) || (nIndex >= implGetCellCount()) )
1201 throw IndexOutOfBoundsException();
1204 void ScAccessibleCsvGrid::ensureValidPosition( sal_Int32 nRow, sal_Int32 nColumn ) const
1206 if( (nRow < 0) || (nRow >= implGetRowCount()) || (nColumn < 0) || (nColumn >= implGetColumnCount()) )
1207 throw IndexOutOfBoundsException();
1210 ScCsvGrid& ScAccessibleCsvGrid::implGetGrid() const
1212 return static_cast< ScCsvGrid& >( implGetControl() );
1215 bool ScAccessibleCsvGrid::implIsColumnSelected( sal_Int32 nColumn ) const
1217 return (nColumn > 0) && implGetGrid().IsSelected( lcl_GetGridColumn( nColumn ) );
1220 void ScAccessibleCsvGrid::implSelectColumn( sal_Int32 nColumn, bool bSelect )
1222 if( nColumn > 0 )
1223 implGetGrid().Select( lcl_GetGridColumn( nColumn ), bSelect );
1226 sal_Int32 ScAccessibleCsvGrid::implGetRowCount() const
1228 return static_cast< sal_Int32 >( implGetGrid().GetLastVisLine() - implGetGrid().GetFirstVisLine() + 2 );
1231 sal_Int32 ScAccessibleCsvGrid::implGetColumnCount() const
1233 return static_cast< sal_Int32 >( implGetGrid().GetColumnCount() + 1 );
1236 sal_Int32 ScAccessibleCsvGrid::implGetSelColumnCount() const
1238 ScCsvGrid& rGrid = implGetGrid();
1239 sal_Int32 nCount = 0;
1240 for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) )
1241 ++nCount;
1242 return nCount;
1245 sal_Int32 ScAccessibleCsvGrid::implGetSelColumn( sal_Int32 nSelColumn ) const
1247 ScCsvGrid& rGrid = implGetGrid();
1248 sal_Int32 nColumn = 0;
1249 for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) )
1251 if( nColumn == nSelColumn )
1252 return static_cast< sal_Int32 >( nColIx + 1 );
1253 ++nColumn;
1255 return 0;
1258 OUString ScAccessibleCsvGrid::implGetCellText( sal_Int32 nRow, sal_Int32 nColumn ) const
1260 ScCsvGrid& rGrid = implGetGrid();
1261 sal_Int32 nLine = nRow + rGrid.GetFirstVisLine() - 1;
1262 OUString aCellStr;
1263 if( (nColumn > 0) && (nRow > 0) )
1264 aCellStr = rGrid.GetCellText( lcl_GetGridColumn( nColumn ), nLine );
1265 else if( nRow > 0 )
1266 aCellStr = OUString::number( nLine + 1 );
1267 else if( nColumn > 0 )
1268 aCellStr = rGrid.GetColumnTypeName( lcl_GetGridColumn( nColumn ) );
1269 return aCellStr;
1272 rtl::Reference<ScAccessibleCsvCell> ScAccessibleCsvGrid::implCreateCellObj( sal_Int32 nRow, sal_Int32 nColumn )
1274 return new ScAccessibleCsvCell(implGetGrid(), implGetCellText(nRow, nColumn), nRow, nColumn);
1277 css::uno::Reference<css::accessibility::XAccessible> SAL_CALL ScAccessibleCsvGrid::getAccessibleParent()
1279 return implGetControl().GetDrawingArea()->get_accessible_parent();
1282 ScAccessibleCsvCell::ScAccessibleCsvCell(
1283 ScCsvGrid& rGrid,
1284 OUString aCellText,
1285 sal_Int32 nRow, sal_Int32 nColumn ) :
1286 ScAccessibleCsvControl( rGrid ),
1287 AccessibleStaticTextBase( SvxEditSourcePtr() ),
1288 maCellText(std::move( aCellText )),
1289 mnLine( nRow ? (nRow + rGrid.GetFirstVisLine() - 1) : CSV_LINE_HEADER ),
1290 mnColumn( lcl_GetGridColumn( nColumn ) ),
1291 mnIndex( nRow * (rGrid.GetColumnCount() + 1) + nColumn )
1293 SetEditSource( implCreateEditSource() );
1296 ScAccessibleCsvCell::~ScAccessibleCsvCell()
1300 void SAL_CALL ScAccessibleCsvCell::disposing()
1302 SolarMutexGuard aGuard;
1303 SetEditSource( SvxEditSourcePtr() );
1304 ScAccessibleCsvControl::disposing();
1307 // XAccessibleComponent -------------------------------------------------------
1309 void SAL_CALL ScAccessibleCsvCell::grabFocus()
1311 SolarMutexGuard aGuard;
1312 ensureAlive();
1313 ScCsvGrid& rGrid = implGetGrid();
1314 rGrid.Execute( CSVCMD_MOVEGRIDCURSOR, rGrid.GetColumnPos( mnColumn ) );
1317 sal_Int32 SAL_CALL ScAccessibleCsvCell::getForeground( )
1319 SolarMutexGuard aGuard;
1320 ensureAlive();
1321 return sal_Int32(Application::GetSettings().GetStyleSettings().GetButtonTextColor());
1324 sal_Int32 SAL_CALL ScAccessibleCsvCell::getBackground( )
1326 SolarMutexGuard aGuard;
1327 ensureAlive();
1328 return sal_Int32(SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor);
1331 // XAccessibleContext -----------------------------------------------------
1333 sal_Int64 SAL_CALL ScAccessibleCsvCell::getAccessibleChildCount()
1335 return AccessibleStaticTextBase::getAccessibleChildCount();
1338 Reference< XAccessible > SAL_CALL ScAccessibleCsvCell::getAccessibleChild( sal_Int64 nIndex )
1340 return AccessibleStaticTextBase::getAccessibleChild( nIndex );
1343 sal_Int64 SAL_CALL ScAccessibleCsvCell::getAccessibleIndexInParent()
1345 SolarMutexGuard aGuard;
1346 ensureAlive();
1347 return mnIndex;
1350 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvCell::getAccessibleRelationSet()
1352 SolarMutexGuard aGuard;
1353 ensureAlive();
1354 return new AccessibleRelationSetHelper();
1357 sal_Int64 SAL_CALL ScAccessibleCsvCell::getAccessibleStateSet()
1359 SolarMutexGuard aGuard;
1360 sal_Int64 nStateSet = implCreateStateSet();
1361 if( isAlive() )
1363 const ScCsvGrid& rGrid = implGetGrid();
1364 nStateSet |= AccessibleStateType::SINGLE_LINE;
1365 if( mnColumn != CSV_COLUMN_HEADER )
1366 nStateSet |= AccessibleStateType::SELECTABLE;
1367 if( rGrid.HasFocus() && (rGrid.GetFocusColumn() == mnColumn) && (mnLine == CSV_LINE_HEADER) )
1368 nStateSet |= AccessibleStateType::ACTIVE;
1369 if( rGrid.IsSelected( mnColumn ) )
1370 nStateSet |= AccessibleStateType::SELECTED;
1372 return nStateSet;
1375 // XInterface -----------------------------------------------------------------
1377 IMPLEMENT_FORWARD_XINTERFACE2( ScAccessibleCsvCell, ScAccessibleCsvControl, AccessibleStaticTextBase )
1379 // XTypeProvider --------------------------------------------------------------
1381 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScAccessibleCsvCell, ScAccessibleCsvControl, AccessibleStaticTextBase )
1383 // helpers --------------------------------------------------------------------
1385 OUString SAL_CALL ScAccessibleCsvCell::getAccessibleName()
1387 return maCellText;
1390 OUString SAL_CALL ScAccessibleCsvCell::getAccessibleDescription()
1392 return OUString();
1395 ScCsvGrid& ScAccessibleCsvCell::implGetGrid() const
1397 return static_cast< ScCsvGrid& >( implGetControl() );
1400 Point ScAccessibleCsvCell::implGetRealPos() const
1402 ScCsvGrid& rGrid = implGetGrid();
1403 return Point(
1404 (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrX() : rGrid.GetColumnX( mnColumn ),
1405 (mnLine == CSV_LINE_HEADER) ? 0 : rGrid.GetY( mnLine ) );
1408 sal_uInt32 ScAccessibleCsvCell::implCalcPixelWidth(sal_uInt32 nChars) const
1410 ScCsvGrid& rGrid = implGetGrid();
1411 return rGrid.GetCharWidth() * nChars;
1414 Size ScAccessibleCsvCell::implGetRealSize() const
1416 ScCsvGrid& rGrid = implGetGrid();
1417 return Size(
1418 (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrWidth() : implCalcPixelWidth( rGrid.GetColumnWidth( mnColumn ) ),
1419 (mnLine == CSV_LINE_HEADER) ? rGrid.GetHdrHeight() : rGrid.GetLineHeight() );
1422 css::awt::Rectangle ScAccessibleCsvCell::implGetBounds()
1424 ScCsvGrid& rGrid = implGetGrid();
1425 tools::Rectangle aClipRect( Point( 0, 0 ), rGrid.GetOutputSizePixel() );
1426 if( mnColumn != CSV_COLUMN_HEADER )
1428 aClipRect.SetLeft( rGrid.GetFirstX() );
1429 aClipRect.SetRight( rGrid.GetLastX() );
1431 if( mnLine != CSV_LINE_HEADER )
1432 aClipRect.SetTop( rGrid.GetHdrHeight() );
1434 tools::Rectangle aRect( implGetRealPos(), implGetRealSize() );
1435 aRect.Intersection( aClipRect );
1436 if( aRect.IsEmpty() )
1437 aRect.SetSize( Size( -1, -1 ) );
1439 return css::awt::Rectangle(aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight());
1442 ::std::unique_ptr< SvxEditSource > ScAccessibleCsvCell::implCreateEditSource()
1444 ScCsvGrid& rGrid = implGetGrid();
1446 ::std::unique_ptr< SvxEditSource > pEditSource( new ScAccessibilityEditSource( std::make_unique<ScAccessibleCsvTextData>(&rGrid.GetDrawingArea()->get_ref_device(), rGrid.GetEditEngine(), maCellText, implGetRealSize()) ) );
1447 return pEditSource;
1450 css::uno::Reference<css::accessibility::XAccessible> SAL_CALL ScAccessibleCsvCell::getAccessibleParent()
1452 ScCsvGrid& rGrid = implGetGrid();
1454 ScAccessibleCsvGrid* pAcc = static_cast<ScAccessibleCsvGrid*>(rGrid.GetAccessible());
1456 return pAcc;
1459 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */