nss: upgrade to release 3.73
[LibreOffice.git] / sc / source / ui / Accessibility / AccessibleCsvControl.cxx
blob5842675f5a343dc3114638084a3e743b6dbe5105
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 <unotools/accessiblestatesethelper.hxx>
35 #include <comphelper/sequence.hxx>
36 #include <scitems.hxx>
37 #include <editeng/fontitem.hxx>
38 #include <editeng/fhgtitem.hxx>
39 #include <editeng/langitem.hxx>
40 #include <csvtablebox.hxx>
41 #include <csvcontrol.hxx>
42 #include <csvruler.hxx>
43 #include <csvgrid.hxx>
44 #include <AccessibleText.hxx>
45 #include <editsrc.hxx>
46 #include <scresid.hxx>
47 #include <strings.hrc>
48 #include <scmod.hxx>
49 #include <svtools/colorcfg.hxx>
50 #include <vcl/svapp.hxx>
51 #include <vcl/settings.hxx>
53 using ::utl::AccessibleRelationSetHelper;
54 using ::utl::AccessibleStateSetHelper;
55 using ::accessibility::AccessibleStaticTextBase;
56 using ::com::sun::star::uno::Any;
57 using ::com::sun::star::uno::Reference;
58 using ::com::sun::star::uno::Sequence;
59 using ::com::sun::star::uno::RuntimeException;
60 using ::com::sun::star::uno::XInterface;
61 using ::com::sun::star::lang::IndexOutOfBoundsException;
62 using ::com::sun::star::beans::PropertyValue;
63 using namespace ::com::sun::star::accessibility;
65 const sal_Unicode cRulerDot = '.';
66 const sal_Unicode cRulerLine = '|';
68 const sal_Int32 CSV_LINE_HEADER = CSV_POS_INVALID;
69 const sal_uInt32 CSV_COLUMN_HEADER = CSV_COLUMN_INVALID;
71 ScAccessibleCsvControl::ScAccessibleCsvControl(ScCsvControl& rControl)
72 : mpControl(&rControl)
76 ScAccessibleCsvControl::~ScAccessibleCsvControl()
78 ensureDisposed();
81 void SAL_CALL ScAccessibleCsvControl::disposing()
83 SolarMutexGuard aGuard;
84 mpControl = nullptr;
85 comphelper::OAccessibleComponentHelper::disposing();
88 // XAccessibleComponent -------------------------------------------------------
90 Reference< XAccessible > SAL_CALL ScAccessibleCsvControl::getAccessibleAtPoint( const css::awt::Point& /* rPoint */ )
92 ensureAlive();
93 return nullptr;
96 void SAL_CALL ScAccessibleCsvControl::grabFocus()
98 SolarMutexGuard aGuard;
99 ensureAlive();
100 implGetControl().GrabFocus();
103 // events ---------------------------------------------------------------------
105 void ScAccessibleCsvControl::SendFocusEvent( bool bFocused )
107 Any aOldAny, aNewAny;
108 if (bFocused)
109 aNewAny <<= AccessibleStateType::FOCUSED;
110 else
111 aOldAny <<= AccessibleStateType::FOCUSED;
112 NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny);
115 void ScAccessibleCsvControl::SendCaretEvent()
117 OSL_FAIL( "ScAccessibleCsvControl::SendCaretEvent - Illegal call" );
120 void ScAccessibleCsvControl::SendVisibleEvent()
122 NotifyAccessibleEvent(AccessibleEventId::VISIBLE_DATA_CHANGED, Any(), Any());
125 void ScAccessibleCsvControl::SendSelectionEvent()
127 NotifyAccessibleEvent(AccessibleEventId::SELECTION_CHANGED, Any(), Any());
130 void ScAccessibleCsvControl::SendTableUpdateEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */, bool /* bAllRows */ )
132 OSL_FAIL( "ScAccessibleCsvControl::SendTableUpdateEvent - Illegal call" );
135 void ScAccessibleCsvControl::SendInsertColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ )
137 OSL_FAIL( "ScAccessibleCsvControl::SendInsertColumnEvent - Illegal call" );
140 void ScAccessibleCsvControl::SendRemoveColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ )
142 OSL_FAIL( "ScAccessibleCsvControl::SendRemoveColumnEvent - Illegal call" );
145 // helpers --------------------------------------------------------------------
147 css::awt::Rectangle ScAccessibleCsvControl::implGetBounds()
149 SolarMutexGuard aGuard;
150 ensureAlive();
151 Size aOutSize(implGetControl().GetOutputSizePixel());
152 return css::awt::Rectangle(0, 0, aOutSize.Width(), aOutSize.Height());
155 ScCsvControl& ScAccessibleCsvControl::implGetControl() const
157 assert(mpControl && "ScAccessibleCsvControl::implGetControl - missing control");
158 return *mpControl;
161 AccessibleStateSetHelper* ScAccessibleCsvControl::implCreateStateSet()
163 SolarMutexGuard aGuard;
164 AccessibleStateSetHelper* pStateSet = new AccessibleStateSetHelper();
165 if (isAlive())
167 const ScCsvControl& rCtrl = implGetControl();
168 pStateSet->AddState( AccessibleStateType::OPAQUE );
169 if( rCtrl.IsEnabled() )
170 pStateSet->AddState( AccessibleStateType::ENABLED );
171 if( rCtrl.IsReallyVisible() )
172 pStateSet->AddState( AccessibleStateType::SHOWING );
173 if( rCtrl.IsVisible() )
174 pStateSet->AddState( AccessibleStateType::VISIBLE );
176 else
177 pStateSet->AddState( AccessibleStateType::DEFUNC );
178 return pStateSet;
181 // Ruler ======================================================================
183 /** Converts a ruler cursor position to API text index. */
184 static sal_Int32 lcl_GetApiPos( sal_Int32 nRulerPos )
186 sal_Int32 nApiPos = nRulerPos;
187 sal_Int32 nStart = (nRulerPos - 1) / 10;
188 sal_Int32 nExp = 1;
189 while( nStart >= nExp )
191 nApiPos += nStart - nExp + 1;
192 nExp *= 10;
194 return ::std::max( nApiPos, static_cast<sal_Int32>(0) );
197 /** Converts an API text index to a ruler cursor position. */
198 static sal_Int32 lcl_GetRulerPos( sal_Int32 nApiPos )
200 sal_Int32 nDiv = 10;
201 sal_Int32 nExp = 10;
202 sal_Int32 nRulerPos = 0;
203 sal_Int32 nApiBase = 0;
204 sal_Int32 nApiLimit = 10;
205 while( nApiPos >= nApiLimit )
207 ++nDiv;
208 nRulerPos = nExp;
209 nExp *= 10;
210 nApiBase = nApiLimit;
211 nApiLimit = lcl_GetApiPos( nExp );
213 sal_Int32 nRelPos = nApiPos - nApiBase;
214 return nRulerPos + nRelPos / nDiv * 10 + ::std::max<sal_Int32>( nRelPos % nDiv - nDiv + 10, 0 );
217 /** Expands the sequence's size and returns the base index of the new inserted elements. */
218 static sal_Int32 lcl_ExpandSequence( Sequence< PropertyValue >& rSeq, sal_Int32 nExp )
220 OSL_ENSURE( nExp > 0, "lcl_ExpandSequence - invalid value" );
221 rSeq.realloc( rSeq.getLength() + nExp );
222 return rSeq.getLength() - nExp;
225 /** Fills the property value rVal with the specified name and value from the item. */
226 static void lcl_FillProperty( PropertyValue& rVal, const OUString& rPropName, const SfxPoolItem& rItem, sal_uInt8 nMID )
228 rVal.Name = rPropName;
229 rItem.QueryValue( rVal.Value, nMID );
232 /** Fills the sequence with all font attributes of rFont. */
233 static void lcl_FillFontAttributes( Sequence< PropertyValue >& rSeq, const vcl::Font& rFont )
235 SvxFontItem aFontItem( rFont.GetFamilyType(), rFont.GetFamilyName(), rFont.GetStyleName(), rFont.GetPitch(), rFont.GetCharSet(), ATTR_FONT );
236 SvxFontHeightItem aHeightItem( rFont.GetFontSize().Height(), 100, ATTR_FONT_HEIGHT );
237 SvxLanguageItem aLangItem( rFont.GetLanguage(), ATTR_FONT_LANGUAGE );
239 sal_Int32 nIndex = lcl_ExpandSequence( rSeq, 7 );
240 lcl_FillProperty( rSeq[ nIndex++ ], "CharFontName", aFontItem, MID_FONT_FAMILY_NAME );
241 lcl_FillProperty( rSeq[ nIndex++ ], "CharFontFamily", aFontItem, MID_FONT_FAMILY );
242 lcl_FillProperty( rSeq[ nIndex++ ], "CharFontStyleName", aFontItem, MID_FONT_STYLE_NAME );
243 lcl_FillProperty( rSeq[ nIndex++ ], "CharFontCharSet", aFontItem, MID_FONT_PITCH );
244 lcl_FillProperty( rSeq[ nIndex++ ], "CharFontPitch", aFontItem, MID_FONT_CHAR_SET );
245 lcl_FillProperty( rSeq[ nIndex++ ], "CharHeight", aHeightItem, MID_FONTHEIGHT );
246 lcl_FillProperty( rSeq[ nIndex++ ], "CharLocale", aLangItem, MID_LANG_LOCALE );
249 ScAccessibleCsvRuler::ScAccessibleCsvRuler(ScCsvRuler& rRuler)
250 : ScAccessibleCsvControl(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_Int32 SAL_CALL ScAccessibleCsvRuler::getAccessibleChildCount()
280 ensureAlive();
281 return 0;
284 Reference< XAccessible > SAL_CALL ScAccessibleCsvRuler::getAccessibleChild( sal_Int32 /* nIndex */ )
286 ensureAlive();
287 throw IndexOutOfBoundsException();
290 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvRuler::getAccessibleRelationSet()
292 SolarMutexGuard aGuard;
293 ensureAlive();
294 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< XInterface > > aSeq( 1 );
304 aSeq[ 0 ] = xAccObj;
305 pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::CONTROLLER_FOR, aSeq ) );
308 return pRelationSet;
311 Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvRuler::getAccessibleStateSet()
313 SolarMutexGuard aGuard;
314 AccessibleStateSetHelper* pStateSet = implCreateStateSet();
315 if( isAlive() )
317 pStateSet->AddState( AccessibleStateType::FOCUSABLE );
318 pStateSet->AddState( AccessibleStateType::SINGLE_LINE );
319 if( implGetRuler().HasFocus() )
320 pStateSet->AddState( AccessibleStateType::FOCUSED );
322 return pStateSet;
325 // XAccessibleText ------------------------------------------------------------
327 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCaretPosition()
329 SolarMutexGuard aGuard;
330 ensureAlive();
331 return lcl_GetApiPos( implGetRuler().GetRulerCursorPos() );
334 sal_Bool SAL_CALL ScAccessibleCsvRuler::setCaretPosition( sal_Int32 nIndex )
336 SolarMutexGuard aGuard;
337 ensureAlive();
338 ensureValidIndex( nIndex );
339 ScCsvRuler& rRuler = implGetRuler();
340 sal_Int32 nOldCursor = rRuler.GetRulerCursorPos();
341 rRuler.Execute( CSVCMD_MOVERULERCURSOR, lcl_GetRulerPos( nIndex ) );
342 return rRuler.GetRulerCursorPos() != nOldCursor;
345 sal_Unicode SAL_CALL ScAccessibleCsvRuler::getCharacter( sal_Int32 nIndex )
347 SolarMutexGuard aGuard;
348 ensureAlive();
349 ensureValidIndex( nIndex );
350 return maBuffer[nIndex];
353 Sequence< PropertyValue > SAL_CALL ScAccessibleCsvRuler::getCharacterAttributes( sal_Int32 nIndex,
354 const css::uno::Sequence< OUString >& /* aRequestedAttributes */ )
356 SolarMutexGuard aGuard;
357 ensureAlive();
358 ensureValidIndexWithEnd( nIndex );
359 Sequence< PropertyValue > aSeq;
360 lcl_FillFontAttributes( aSeq, implGetRuler().GetDrawingArea()->get_ref_device().GetFont() );
361 return aSeq;
364 css::awt::Rectangle SAL_CALL ScAccessibleCsvRuler::getCharacterBounds( sal_Int32 nIndex )
366 SolarMutexGuard aGuard;
367 ensureAlive();
368 ensureValidIndexWithEnd( nIndex );
369 ScCsvRuler& rRuler = implGetRuler();
370 Point aPos( rRuler.GetX( lcl_GetRulerPos( nIndex ) ) - rRuler.GetCharWidth() / 2, 0 );
371 css::awt::Rectangle aRect( aPos.X(), aPos.Y(), rRuler.GetCharWidth(), rRuler.GetOutputSizePixel().Height() );
372 // do not return rectangle out of window
373 sal_Int32 nWidth = rRuler.GetOutputSizePixel().Width();
374 if( aRect.X >= nWidth )
375 throw IndexOutOfBoundsException();
376 if( aRect.X + aRect.Width > nWidth )
377 aRect.Width = nWidth - aRect.X;
378 return aRect;
381 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCharacterCount()
383 SolarMutexGuard aGuard;
384 ensureAlive();
385 return implGetTextLength();
388 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getIndexAtPoint( const css::awt::Point& rPoint )
390 SolarMutexGuard aGuard;
391 ensureAlive();
392 ScCsvRuler& rRuler = implGetRuler();
393 // use object's coordinate system, convert to API position
394 return lcl_GetApiPos( ::std::clamp( rRuler.GetPosFromX( rPoint.X ), sal_Int32(0), rRuler.GetPosCount() ) );
397 OUString SAL_CALL ScAccessibleCsvRuler::getSelectedText()
399 ensureAlive();
400 return OUString();
403 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionStart()
405 ensureAlive();
406 return -1;
409 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionEnd()
411 ensureAlive();
412 return -1;
415 sal_Bool SAL_CALL ScAccessibleCsvRuler::setSelection( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ )
417 ensureAlive();
418 return false;
421 OUString SAL_CALL ScAccessibleCsvRuler::getText()
423 SolarMutexGuard aGuard;
424 ensureAlive();
425 return OUString( maBuffer.getStr(), implGetTextLength() );
428 OUString SAL_CALL ScAccessibleCsvRuler::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
430 SolarMutexGuard aGuard;
431 ensureAlive();
432 ensureValidRange( nStartIndex, nEndIndex );
433 return OUString( maBuffer.getStr() + nStartIndex, nEndIndex - nStartIndex );
436 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextAtIndex( sal_Int32 nIndex, sal_Int16 nTextType )
438 SolarMutexGuard aGuard;
439 ensureAlive();
441 TextSegment aResult;
442 aResult.SegmentStart = -1;
443 aResult.SegmentEnd = -1;
445 if( (nIndex == implGetTextLength()) && (nTextType != AccessibleTextType::LINE) )
446 return aResult;
448 ensureValidIndex( nIndex );
450 OUStringBuffer aResultText; // will be assigned to aResult.SegmentText below
451 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
453 switch( nTextType )
455 // single character
456 case AccessibleTextType::CHARACTER:
458 aResult.SegmentStart = nIndex;
459 aResultText.append(maBuffer[nIndex]);
461 break;
463 // entire number or single dot/line
464 case AccessibleTextType::WORD:
465 case AccessibleTextType::GLYPH:
466 aResult.SegmentStart = nIndex;
467 if( nRulerPos % 10 )
468 aResultText.append(maBuffer[nIndex]);
469 else
470 aResultText.append( nRulerPos ); // string representation of sal_Int32!!!
471 break;
473 // entire text
474 case AccessibleTextType::SENTENCE:
475 case AccessibleTextType::PARAGRAPH:
476 case AccessibleTextType::LINE:
477 aResult.SegmentStart = 0;
478 aResultText.append( maBuffer.getStr(), implGetTextLength() );
479 break;
481 // equal-formatted text
482 case AccessibleTextType::ATTRIBUTE_RUN:
484 sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex );
485 sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex );
486 aResult.SegmentStart = nFirstIndex;
487 aResultText.append( maBuffer.getStr() + nFirstIndex, nLastIndex - nFirstIndex + 1 );
489 break;
491 default:
492 throw RuntimeException();
495 aResult.SegmentText = aResultText.makeStringAndClear();
496 aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
497 return aResult;
500 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 nTextType )
502 SolarMutexGuard aGuard;
503 ensureAlive();
504 ensureValidIndexWithEnd( nIndex );
506 TextSegment aResult;
507 aResult.SegmentStart = -1;
508 aResult.SegmentEnd = -1;
510 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
512 switch( nTextType )
514 // single character
515 case AccessibleTextType::CHARACTER:
516 if( nIndex > 0 )
517 aResult = getTextAtIndex( nIndex - 1, nTextType );
518 // else empty
519 break;
521 // entire number or single dot/line
522 case AccessibleTextType::WORD:
523 case AccessibleTextType::GLYPH:
524 if( nRulerPos > 0 )
525 aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos - 1 ), nTextType );
526 // else empty
527 break;
529 // entire text
530 case AccessibleTextType::SENTENCE:
531 case AccessibleTextType::PARAGRAPH:
532 case AccessibleTextType::LINE:
533 // empty
534 break;
536 // equal-formatted text
537 case AccessibleTextType::ATTRIBUTE_RUN:
539 sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex );
540 if( nFirstIndex > 0 )
541 aResult = getTextAtIndex( nFirstIndex - 1, nTextType );
542 // else empty
544 break;
546 default:
547 throw RuntimeException();
549 return aResult;
552 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 nTextType )
554 SolarMutexGuard aGuard;
555 ensureAlive();
556 ensureValidIndexWithEnd( nIndex );
558 TextSegment aResult;
559 aResult.SegmentStart = -1;
560 aResult.SegmentEnd = -1;
562 sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
563 sal_Int32 nLastValid = implGetTextLength();
565 switch( nTextType )
567 // single character
568 case AccessibleTextType::CHARACTER:
569 if( nIndex < nLastValid )
570 aResult = getTextAtIndex( nIndex + 1, nTextType );
571 // else empty
572 break;
574 // entire number or single dot/line
575 case AccessibleTextType::WORD:
576 case AccessibleTextType::GLYPH:
577 if( nRulerPos < implGetRuler().GetPosCount() )
578 aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos + 1 ), nTextType );
579 // else empty
580 break;
582 // entire text
583 case AccessibleTextType::SENTENCE:
584 case AccessibleTextType::PARAGRAPH:
585 case AccessibleTextType::LINE:
586 // empty
587 break;
589 // equal-formatted text
590 case AccessibleTextType::ATTRIBUTE_RUN:
592 sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex );
593 if( nLastIndex < nLastValid )
594 aResult = getTextAtIndex( nLastIndex + 1, nTextType );
595 // else empty
597 break;
599 default:
600 throw RuntimeException();
602 return aResult;
605 sal_Bool SAL_CALL ScAccessibleCsvRuler::copyText( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ )
607 ensureAlive();
608 return false;
611 sal_Bool SAL_CALL ScAccessibleCsvRuler::scrollSubstringTo( sal_Int32 /* nStartIndex */, sal_Int32/* nEndIndex */, AccessibleScrollType /* aScrollType */ )
613 return false;
616 // XInterface -----------------------------------------------------------------
618 Any SAL_CALL ScAccessibleCsvRuler::queryInterface( const css::uno::Type& rType )
620 Any aAny( ScAccessibleCsvRulerImpl::queryInterface( rType ) );
621 return aAny.hasValue() ? aAny : ScAccessibleCsvControl::queryInterface( rType );
624 void SAL_CALL ScAccessibleCsvRuler::acquire() throw ()
626 ScAccessibleCsvControl::acquire();
629 void SAL_CALL ScAccessibleCsvRuler::release() throw ()
631 ScAccessibleCsvControl::release();
634 // XTypeProvider --------------------------------------------------------------
636 Sequence< css::uno::Type > SAL_CALL ScAccessibleCsvRuler::getTypes()
638 return ::comphelper::concatSequences( ScAccessibleCsvControl::getTypes(),
639 Sequence { cppu::UnoType<XAccessibleText>::get() });
642 Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvRuler::getImplementationId()
644 return css::uno::Sequence<sal_Int8>();
647 // events ---------------------------------------------------------------------
649 void ScAccessibleCsvRuler::SendCaretEvent()
651 sal_Int32 nPos = implGetRuler().GetRulerCursorPos();
652 if (nPos != CSV_POS_INVALID)
654 Any aOldValue, aNewValue;
655 aNewValue <<= nPos;
656 NotifyAccessibleEvent( AccessibleEventId::CARET_CHANGED, aOldValue, aNewValue );
660 // helpers --------------------------------------------------------------------
662 OUString SAL_CALL ScAccessibleCsvRuler::getAccessibleName()
664 return ScResId( STR_ACC_CSVRULER_NAME );
667 OUString SAL_CALL ScAccessibleCsvRuler::getAccessibleDescription()
669 return ScResId( STR_ACC_CSVRULER_DESCR );
672 void ScAccessibleCsvRuler::ensureValidIndex( sal_Int32 nIndex ) const
674 if( (nIndex < 0) || (nIndex >= implGetTextLength()) )
675 throw IndexOutOfBoundsException();
678 void ScAccessibleCsvRuler::ensureValidIndexWithEnd( sal_Int32 nIndex ) const
680 if( (nIndex < 0) || (nIndex > implGetTextLength()) )
681 throw IndexOutOfBoundsException();
684 void ScAccessibleCsvRuler::ensureValidRange( sal_Int32& rnStartIndex, sal_Int32& rnEndIndex ) const
686 if( rnStartIndex > rnEndIndex )
687 ::std::swap( rnStartIndex, rnEndIndex );
688 if( (rnStartIndex < 0) || (rnEndIndex > implGetTextLength()) )
689 throw IndexOutOfBoundsException();
692 ScCsvRuler& ScAccessibleCsvRuler::implGetRuler() const
694 return static_cast< ScCsvRuler& >( implGetControl() );
697 void ScAccessibleCsvRuler::constructStringBuffer()
699 SolarMutexGuard aGuard;
700 ensureAlive();
701 // extend existing string buffer to new ruler size
702 sal_Int32 nRulerCount = implGetRuler().GetPosCount();
703 sal_Int32 nRulerPos = lcl_GetRulerPos( maBuffer.getLength() );
704 for( ; nRulerPos <= nRulerCount; ++nRulerPos ) // include last position
706 switch( nRulerPos % 10 )
708 case 0: maBuffer.append( nRulerPos ); break;
709 case 5: maBuffer.append( cRulerLine ); break;
710 default: maBuffer.append( cRulerDot );
715 sal_Int32 ScAccessibleCsvRuler::implGetTextLength() const
717 return lcl_GetApiPos( implGetRuler().GetPosCount() + 1 );
720 bool ScAccessibleCsvRuler::implHasSplit( sal_Int32 nApiPos )
722 sal_Int32 nRulerPos = lcl_GetRulerPos( nApiPos );
723 return implGetRuler().HasSplit( nRulerPos ) && (nApiPos == lcl_GetApiPos( nRulerPos ));
726 sal_Int32 ScAccessibleCsvRuler::implGetFirstEqualFormatted( sal_Int32 nApiPos )
728 bool bSplit = implHasSplit( nApiPos );
729 while( (nApiPos > 0) && (implHasSplit( nApiPos - 1 ) == bSplit) )
730 --nApiPos;
731 return nApiPos;
734 sal_Int32 ScAccessibleCsvRuler::implGetLastEqualFormatted( sal_Int32 nApiPos )
736 bool bSplit = implHasSplit( nApiPos );
737 sal_Int32 nLength = implGetTextLength();
738 while( (nApiPos < nLength - 1) && (implHasSplit( nApiPos + 1 ) == bSplit) )
739 ++nApiPos;
740 return nApiPos;
743 css::uno::Reference<css::accessibility::XAccessible> SAL_CALL ScAccessibleCsvRuler::getAccessibleParent()
745 return implGetControl().GetDrawingArea()->get_accessible_parent();
748 // Grid =======================================================================
750 /** Converts a grid columnm index to an API column index. */
751 static sal_Int32 lcl_GetApiColumn( sal_uInt32 nGridColumn )
753 return (nGridColumn != CSV_COLUMN_HEADER) ? static_cast< sal_Int32 >( nGridColumn + 1 ) : 0;
756 /** Converts an API columnm index to a ScCsvGrid column index. */
757 static sal_uInt32 lcl_GetGridColumn( sal_Int32 nApiColumn )
759 return (nApiColumn > 0) ? static_cast< sal_uInt32 >( nApiColumn - 1 ) : CSV_COLUMN_HEADER;
762 ScAccessibleCsvGrid::ScAccessibleCsvGrid(ScCsvGrid& rGrid)
763 : ScAccessibleCsvControl(rGrid)
767 ScAccessibleCsvGrid::~ScAccessibleCsvGrid()
769 ensureDisposed();
772 void ScAccessibleCsvGrid::disposing()
774 SolarMutexGuard aGuard;
775 for (auto& rEntry : maAccessibleChildren)
776 rEntry.second->dispose();
777 maAccessibleChildren.clear();
778 ScAccessibleCsvControl::disposing();
781 // XAccessibleComponent -------------------------------------------------------
783 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleAtPoint( const css::awt::Point& rPoint )
785 Reference< XAccessible > xRet;
786 if( containsPoint( rPoint ) )
788 SolarMutexGuard aGuard;
789 ensureAlive();
791 const ScCsvGrid& rGrid = implGetGrid();
792 // #102679#; use <= instead of <, because the offset is the size and not the point
793 sal_Int32 nColumn = ((rGrid.GetFirstX() <= rPoint.X) && (rPoint.X <= rGrid.GetLastX())) ?
794 lcl_GetApiColumn( rGrid.GetColumnFromX( rPoint.X ) ) : 0;
795 sal_Int32 nRow = (rPoint.Y >= rGrid.GetHdrHeight()) ?
796 (rGrid.GetLineFromY( rPoint.Y ) - rGrid.GetFirstVisLine() + 1) : 0;
797 xRet = getAccessibleCell(nRow, nColumn);
799 return xRet;
802 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getForeground( )
804 SolarMutexGuard aGuard;
805 ensureAlive();
806 return sal_Int32(Application::GetSettings().GetStyleSettings().GetButtonTextColor());
809 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getBackground( )
811 SolarMutexGuard aGuard;
812 ensureAlive();
813 return sal_Int32(SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor);
816 // XAccessibleContext ---------------------------------------------------------
818 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleChildCount()
820 SolarMutexGuard aGuard;
821 ensureAlive();
822 return implGetCellCount();
825 Reference<XAccessible> ScAccessibleCsvGrid::getAccessibleCell(sal_Int32 nRow, sal_Int32 nColumn)
827 sal_Int32 nIndex = implGetIndex(nRow, nColumn);
829 XAccessibleSet::iterator aI = maAccessibleChildren.lower_bound(nIndex);
830 if (aI != maAccessibleChildren.end() && !(maAccessibleChildren.key_comp()(nIndex, aI->first)))
832 // key already exists
833 return Reference<XAccessible>(aI->second.get());
835 // key does not exist
836 rtl::Reference<ScAccessibleCsvCell> xNew = implCreateCellObj(nRow, nColumn);
837 maAccessibleChildren.insert(aI, XAccessibleSet::value_type(nIndex, xNew));
838 return Reference<XAccessible>(xNew.get());
841 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleChild( sal_Int32 nIndex )
843 SolarMutexGuard aGuard;
844 ensureAlive();
845 ensureValidIndex( nIndex );
847 return getAccessibleCell(implGetRow(nIndex), implGetColumn(nIndex));
850 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleRelationSet()
852 SolarMutexGuard aGuard;
853 ensureAlive();
854 AccessibleRelationSetHelper* pRelationSet = new AccessibleRelationSetHelper();
856 ScCsvGrid& rGrid = implGetGrid();
857 ScCsvTableBox* pTableBox = rGrid.GetTableBox();
858 ScCsvRuler& rRuler = pTableBox->GetRuler();
860 if (rRuler.IsVisible())
862 css::uno::Reference<css::accessibility::XAccessible> xAccObj(static_cast<ScAccessibleCsvGrid*>(rRuler.GetAccessible()));
863 if( xAccObj.is() )
865 Sequence< Reference< XInterface > > aSeq( 1 );
866 aSeq[ 0 ] = xAccObj;
867 pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::CONTROLLED_BY, aSeq ) );
871 return pRelationSet;
874 Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleStateSet()
876 SolarMutexGuard aGuard;
877 AccessibleStateSetHelper* pStateSet = implCreateStateSet();
878 if( isAlive() )
880 pStateSet->AddState( AccessibleStateType::FOCUSABLE );
881 pStateSet->AddState( AccessibleStateType::MULTI_SELECTABLE );
882 pStateSet->AddState( AccessibleStateType::MANAGES_DESCENDANTS );
883 if( implGetGrid().HasFocus() )
884 pStateSet->AddState( AccessibleStateType::FOCUSED );
886 else
887 pStateSet->AddState( AccessibleStateType::DEFUNC );
888 return pStateSet;
891 // XAccessibleTable -----------------------------------------------------------
893 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowCount()
895 SolarMutexGuard aGuard;
896 ensureAlive();
897 return implGetRowCount();
900 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnCount()
902 SolarMutexGuard aGuard;
903 ensureAlive();
904 return implGetColumnCount();
907 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleRowDescription( sal_Int32 nRow )
909 SolarMutexGuard aGuard;
910 ensureAlive();
911 ensureValidPosition( nRow, 0 );
912 return implGetCellText( nRow, 0 );
915 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnDescription( sal_Int32 nColumn )
917 SolarMutexGuard aGuard;
918 ensureAlive();
919 ensureValidPosition( 0, nColumn );
920 return implGetCellText( 0, nColumn );
923 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
925 ensureAlive();
926 ensureValidPosition( nRow, nColumn );
927 return 1;
930 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
932 ensureAlive();
933 ensureValidPosition( nRow, nColumn );
934 return 1;
937 Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleRowHeaders()
939 ensureAlive();
940 return nullptr;
943 Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnHeaders()
945 ensureAlive();
946 return nullptr;
949 Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleRows()
951 ensureAlive();
952 return Sequence< sal_Int32 >();
955 Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleColumns()
957 SolarMutexGuard aGuard;
958 ensureAlive();
960 ScCsvGrid& rGrid = implGetGrid();
961 Sequence< sal_Int32 > aSeq( implGetColumnCount() );
963 sal_Int32 nSeqIx = 0;
964 sal_uInt32 nColIx = rGrid.GetFirstSelected();
965 for( ; nColIx != CSV_COLUMN_INVALID; ++nSeqIx, nColIx = rGrid.GetNextSelected( nColIx ) )
966 aSeq[ nSeqIx ] = lcl_GetApiColumn( nColIx );
968 aSeq.realloc( nSeqIx );
969 return aSeq;
972 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleRowSelected( sal_Int32 /* nRow */ )
974 ensureAlive();
975 return false;
978 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleColumnSelected( sal_Int32 nColumn )
980 SolarMutexGuard aGuard;
981 ensureAlive();
982 ensureValidIndex( nColumn );
983 return implIsColumnSelected( nColumn );
986 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
988 SolarMutexGuard aGuard;
989 ensureAlive();
990 ensureValidPosition( nRow, nColumn );
991 return getAccessibleCell(nRow, nColumn);
994 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCaption()
996 ensureAlive();
997 return nullptr;
1000 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleSummary()
1002 ensureAlive();
1003 return nullptr;
1006 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 nColumn )
1008 return isAccessibleColumnSelected( nColumn );
1011 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
1013 SolarMutexGuard aGuard;
1014 ensureAlive();
1015 ensureValidPosition( nRow, nColumn );
1016 return implGetIndex( nRow, nColumn );
1019 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRow( sal_Int32 nChildIndex )
1021 SolarMutexGuard aGuard;
1022 ensureAlive();
1023 ensureValidIndex( nChildIndex );
1024 return implGetRow( nChildIndex );
1027 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumn( sal_Int32 nChildIndex )
1029 SolarMutexGuard aGuard;
1030 ensureAlive();
1031 ensureValidIndex( nChildIndex );
1032 return implGetColumn( nChildIndex );
1035 // XAccessibleSelection -------------------------------------------------------
1037 void SAL_CALL ScAccessibleCsvGrid::selectAccessibleChild( sal_Int32 nChildIndex )
1039 SolarMutexGuard aGuard;
1040 ensureAlive();
1041 ensureValidIndex( nChildIndex );
1042 sal_Int32 nColumn = implGetColumn( nChildIndex );
1043 if( nChildIndex == 0 )
1044 implGetGrid().SelectAll();
1045 else
1046 implSelectColumn( nColumn, true );
1049 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleChildSelected( sal_Int32 nChildIndex )
1051 SolarMutexGuard aGuard;
1052 ensureAlive();
1053 ensureValidIndex( nChildIndex );
1054 sal_Int32 nColumn = implGetColumn( nChildIndex );
1055 return implIsColumnSelected( nColumn );
1058 void SAL_CALL ScAccessibleCsvGrid::clearAccessibleSelection()
1060 SolarMutexGuard aGuard;
1061 ensureAlive();
1062 implGetGrid().SelectAll( false );
1065 void SAL_CALL ScAccessibleCsvGrid::selectAllAccessibleChildren()
1067 selectAccessibleChild( 0 );
1070 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChildCount()
1072 SolarMutexGuard aGuard;
1073 ensureAlive();
1074 return implGetRowCount() * implGetSelColumnCount();
1077 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
1079 SolarMutexGuard aGuard;
1080 ensureAlive();
1081 sal_Int32 nColumns = implGetSelColumnCount();
1082 if( nColumns == 0 )
1083 throw IndexOutOfBoundsException();
1085 sal_Int32 nRow = nSelectedChildIndex / nColumns;
1086 sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns );
1087 return getAccessibleCellAt( nRow, nColumn );
1090 void SAL_CALL ScAccessibleCsvGrid::deselectAccessibleChild( sal_Int32 nSelectedChildIndex )
1092 SolarMutexGuard aGuard;
1093 ensureAlive();
1094 sal_Int32 nColumns = implGetSelColumnCount();
1095 if( nColumns == 0 )
1096 throw IndexOutOfBoundsException();
1098 sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns );
1099 ensureValidPosition( nSelectedChildIndex / nColumns, nColumn );
1100 if( nColumn > 0 )
1101 implSelectColumn( nColumn, false );
1104 // XInterface -----------------------------------------------------------------
1106 Any SAL_CALL ScAccessibleCsvGrid::queryInterface( const css::uno::Type& rType )
1108 Any aAny( ScAccessibleCsvGridImpl::queryInterface( rType ) );
1109 return aAny.hasValue() ? aAny : ScAccessibleCsvControl::queryInterface( rType );
1112 void SAL_CALL ScAccessibleCsvGrid::acquire() throw ()
1114 ScAccessibleCsvControl::acquire();
1117 void SAL_CALL ScAccessibleCsvGrid::release() throw ()
1119 ScAccessibleCsvControl::release();
1122 // XTypeProvider --------------------------------------------------------------
1124 Sequence< css::uno::Type > SAL_CALL ScAccessibleCsvGrid::getTypes()
1126 return ::comphelper::concatSequences( ScAccessibleCsvControl::getTypes(),
1127 Sequence {
1128 cppu::UnoType<XAccessibleTable>::get(),
1129 cppu::UnoType<XAccessibleSelection>::get() });
1132 Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvGrid::getImplementationId()
1134 return css::uno::Sequence<sal_Int8>();
1137 // events ---------------------------------------------------------------------
1139 void ScAccessibleCsvGrid::SendFocusEvent( bool bFocused )
1141 ScAccessibleCsvControl::SendFocusEvent( bFocused );
1142 Any aOldAny, aNewAny;
1143 (bFocused ? aNewAny : aOldAny) <<=
1144 getAccessibleCellAt( 0, lcl_GetApiColumn( implGetGrid().GetFocusColumn() ) );
1145 NotifyAccessibleEvent(AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldAny, aNewAny);
1148 void ScAccessibleCsvGrid::SendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows )
1150 if( nFirstColumn <= nLastColumn )
1152 AccessibleTableModelChange aModelChange(
1153 AccessibleTableModelChangeType::UPDATE, 0, bAllRows ? implGetRowCount() - 1 : 0,
1154 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1155 Any aOldAny, aNewAny;
1156 aNewAny <<= aModelChange;
1157 NotifyAccessibleEvent(AccessibleEventId::TABLE_MODEL_CHANGED, aOldAny, aNewAny);
1161 void ScAccessibleCsvGrid::SendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
1163 if( nFirstColumn <= nLastColumn )
1165 AccessibleTableModelChange aModelChange(
1166 AccessibleTableModelChangeType::INSERT, 0, implGetRowCount() - 1,
1167 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1168 Any aOldAny, aNewAny;
1169 aNewAny <<= aModelChange;
1170 NotifyAccessibleEvent(AccessibleEventId::TABLE_MODEL_CHANGED, aOldAny, aNewAny);
1174 void ScAccessibleCsvGrid::SendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
1176 if( nFirstColumn <= nLastColumn )
1178 AccessibleTableModelChange aModelChange(
1179 AccessibleTableModelChangeType::DELETE, 0, implGetRowCount() - 1,
1180 lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1181 Any aOldAny, aNewAny;
1182 aNewAny <<= aModelChange;
1183 NotifyAccessibleEvent(AccessibleEventId::TABLE_MODEL_CHANGED, aOldAny, aNewAny);
1187 // helpers --------------------------------------------------------------------
1189 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleName()
1191 return ScResId( STR_ACC_CSVGRID_NAME );
1194 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleDescription()
1196 return ScResId( STR_ACC_CSVGRID_DESCR );
1199 void ScAccessibleCsvGrid::ensureValidIndex( sal_Int32 nIndex ) const
1201 if( (nIndex < 0) || (nIndex >= implGetCellCount()) )
1202 throw IndexOutOfBoundsException();
1205 void ScAccessibleCsvGrid::ensureValidPosition( sal_Int32 nRow, sal_Int32 nColumn ) const
1207 if( (nRow < 0) || (nRow >= implGetRowCount()) || (nColumn < 0) || (nColumn >= implGetColumnCount()) )
1208 throw IndexOutOfBoundsException();
1211 ScCsvGrid& ScAccessibleCsvGrid::implGetGrid() const
1213 return static_cast< ScCsvGrid& >( implGetControl() );
1216 bool ScAccessibleCsvGrid::implIsColumnSelected( sal_Int32 nColumn ) const
1218 return (nColumn > 0) && implGetGrid().IsSelected( lcl_GetGridColumn( nColumn ) );
1221 void ScAccessibleCsvGrid::implSelectColumn( sal_Int32 nColumn, bool bSelect )
1223 if( nColumn > 0 )
1224 implGetGrid().Select( lcl_GetGridColumn( nColumn ), bSelect );
1227 sal_Int32 ScAccessibleCsvGrid::implGetRowCount() const
1229 return static_cast< sal_Int32 >( implGetGrid().GetLastVisLine() - implGetGrid().GetFirstVisLine() + 2 );
1232 sal_Int32 ScAccessibleCsvGrid::implGetColumnCount() const
1234 return static_cast< sal_Int32 >( implGetGrid().GetColumnCount() + 1 );
1237 sal_Int32 ScAccessibleCsvGrid::implGetSelColumnCount() const
1239 ScCsvGrid& rGrid = implGetGrid();
1240 sal_Int32 nCount = 0;
1241 for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) )
1242 ++nCount;
1243 return nCount;
1246 sal_Int32 ScAccessibleCsvGrid::implGetSelColumn( sal_Int32 nSelColumn ) const
1248 ScCsvGrid& rGrid = implGetGrid();
1249 sal_Int32 nColumn = 0;
1250 for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) )
1252 if( nColumn == nSelColumn )
1253 return static_cast< sal_Int32 >( nColIx + 1 );
1254 ++nColumn;
1256 return 0;
1259 OUString ScAccessibleCsvGrid::implGetCellText( sal_Int32 nRow, sal_Int32 nColumn ) const
1261 ScCsvGrid& rGrid = implGetGrid();
1262 sal_Int32 nLine = nRow + rGrid.GetFirstVisLine() - 1;
1263 OUString aCellStr;
1264 if( (nColumn > 0) && (nRow > 0) )
1265 aCellStr = rGrid.GetCellText( lcl_GetGridColumn( nColumn ), nLine );
1266 else if( nRow > 0 )
1267 aCellStr = OUString::number( nLine + 1 );
1268 else if( nColumn > 0 )
1269 aCellStr = rGrid.GetColumnTypeName( lcl_GetGridColumn( nColumn ) );
1270 return aCellStr;
1273 ScAccessibleCsvCell* ScAccessibleCsvGrid::implCreateCellObj( sal_Int32 nRow, sal_Int32 nColumn )
1275 return new ScAccessibleCsvCell(implGetGrid(), implGetCellText(nRow, nColumn), nRow, nColumn);
1278 css::uno::Reference<css::accessibility::XAccessible> SAL_CALL ScAccessibleCsvGrid::getAccessibleParent()
1280 return implGetControl().GetDrawingArea()->get_accessible_parent();
1283 ScAccessibleCsvCell::ScAccessibleCsvCell(
1284 ScCsvGrid& rGrid,
1285 const OUString& rCellText,
1286 sal_Int32 nRow, sal_Int32 nColumn ) :
1287 ScAccessibleCsvControl( rGrid ),
1288 AccessibleStaticTextBase( SvxEditSourcePtr() ),
1289 maCellText( rCellText ),
1290 mnLine( nRow ? (nRow + rGrid.GetFirstVisLine() - 1) : CSV_LINE_HEADER ),
1291 mnColumn( lcl_GetGridColumn( nColumn ) ),
1292 mnIndex( nRow * (rGrid.GetColumnCount() + 1) + nColumn )
1294 SetEditSource( implCreateEditSource() );
1297 ScAccessibleCsvCell::~ScAccessibleCsvCell()
1301 void SAL_CALL ScAccessibleCsvCell::disposing()
1303 SolarMutexGuard aGuard;
1304 SetEditSource( SvxEditSourcePtr() );
1305 ScAccessibleCsvControl::disposing();
1308 // XAccessibleComponent -------------------------------------------------------
1310 void SAL_CALL ScAccessibleCsvCell::grabFocus()
1312 SolarMutexGuard aGuard;
1313 ensureAlive();
1314 ScCsvGrid& rGrid = implGetGrid();
1315 rGrid.Execute( CSVCMD_MOVEGRIDCURSOR, rGrid.GetColumnPos( mnColumn ) );
1318 sal_Int32 SAL_CALL ScAccessibleCsvCell::getForeground( )
1320 SolarMutexGuard aGuard;
1321 ensureAlive();
1322 return sal_Int32(Application::GetSettings().GetStyleSettings().GetButtonTextColor());
1325 sal_Int32 SAL_CALL ScAccessibleCsvCell::getBackground( )
1327 SolarMutexGuard aGuard;
1328 ensureAlive();
1329 return sal_Int32(SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor);
1332 // XAccessibleContext -----------------------------------------------------
1334 sal_Int32 SAL_CALL ScAccessibleCsvCell::getAccessibleChildCount()
1336 return AccessibleStaticTextBase::getAccessibleChildCount();
1339 Reference< XAccessible > SAL_CALL ScAccessibleCsvCell::getAccessibleChild( sal_Int32 nIndex )
1341 return AccessibleStaticTextBase::getAccessibleChild( nIndex );
1344 sal_Int32 SAL_CALL ScAccessibleCsvCell::getAccessibleIndexInParent()
1346 SolarMutexGuard aGuard;
1347 ensureAlive();
1348 return mnIndex;
1351 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvCell::getAccessibleRelationSet()
1353 SolarMutexGuard aGuard;
1354 ensureAlive();
1355 return new AccessibleRelationSetHelper();
1358 Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvCell::getAccessibleStateSet()
1360 SolarMutexGuard aGuard;
1361 AccessibleStateSetHelper* pStateSet = implCreateStateSet();
1362 if( isAlive() )
1364 const ScCsvGrid& rGrid = implGetGrid();
1365 pStateSet->AddState( AccessibleStateType::SINGLE_LINE );
1366 if( mnColumn != CSV_COLUMN_HEADER )
1367 pStateSet->AddState( AccessibleStateType::SELECTABLE );
1368 if( rGrid.HasFocus() && (rGrid.GetFocusColumn() == mnColumn) && (mnLine == CSV_LINE_HEADER) )
1369 pStateSet->AddState( AccessibleStateType::ACTIVE );
1370 if( rGrid.IsSelected( mnColumn ) )
1371 pStateSet->AddState( AccessibleStateType::SELECTED );
1373 return pStateSet;
1376 // XInterface -----------------------------------------------------------------
1378 IMPLEMENT_FORWARD_XINTERFACE2( ScAccessibleCsvCell, ScAccessibleCsvControl, AccessibleStaticTextBase )
1380 // XTypeProvider --------------------------------------------------------------
1382 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScAccessibleCsvCell, ScAccessibleCsvControl, AccessibleStaticTextBase )
1384 // helpers --------------------------------------------------------------------
1386 OUString SAL_CALL ScAccessibleCsvCell::getAccessibleName()
1388 return maCellText;
1391 OUString SAL_CALL ScAccessibleCsvCell::getAccessibleDescription()
1393 return OUString();
1396 ScCsvGrid& ScAccessibleCsvCell::implGetGrid() const
1398 return static_cast< ScCsvGrid& >( implGetControl() );
1401 Point ScAccessibleCsvCell::implGetRealPos() const
1403 ScCsvGrid& rGrid = implGetGrid();
1404 return Point(
1405 (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrX() : rGrid.GetColumnX( mnColumn ),
1406 (mnLine == CSV_LINE_HEADER) ? 0 : rGrid.GetY( mnLine ) );
1409 sal_uInt32 ScAccessibleCsvCell::implCalcPixelWidth(sal_uInt32 nChars) const
1411 ScCsvGrid& rGrid = implGetGrid();
1412 return rGrid.GetCharWidth() * nChars;
1415 Size ScAccessibleCsvCell::implGetRealSize() const
1417 ScCsvGrid& rGrid = implGetGrid();
1418 return Size(
1419 (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrWidth() : implCalcPixelWidth( rGrid.GetColumnWidth( mnColumn ) ),
1420 (mnLine == CSV_LINE_HEADER) ? rGrid.GetHdrHeight() : rGrid.GetLineHeight() );
1423 css::awt::Rectangle ScAccessibleCsvCell::implGetBounds()
1425 ScCsvGrid& rGrid = implGetGrid();
1426 tools::Rectangle aClipRect( Point( 0, 0 ), rGrid.GetOutputSizePixel() );
1427 if( mnColumn != CSV_COLUMN_HEADER )
1429 aClipRect.SetLeft( rGrid.GetFirstX() );
1430 aClipRect.SetRight( rGrid.GetLastX() );
1432 if( mnLine != CSV_LINE_HEADER )
1433 aClipRect.SetTop( rGrid.GetHdrHeight() );
1435 tools::Rectangle aRect( implGetRealPos(), implGetRealSize() );
1436 aRect.Intersection( aClipRect );
1437 if( aRect.IsEmpty() )
1438 aRect.SetSize( Size( -1, -1 ) );
1440 return css::awt::Rectangle(aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight());
1443 ::std::unique_ptr< SvxEditSource > ScAccessibleCsvCell::implCreateEditSource()
1445 ScCsvGrid& rGrid = implGetGrid();
1447 ::std::unique_ptr< SvxEditSource > pEditSource( new ScAccessibilityEditSource( std::make_unique<ScAccessibleCsvTextData>(&rGrid.GetDrawingArea()->get_ref_device(), rGrid.GetEditEngine(), maCellText, implGetRealSize()) ) );
1448 return pEditSource;
1451 css::uno::Reference<css::accessibility::XAccessible> SAL_CALL ScAccessibleCsvCell::getAccessibleParent()
1453 ScCsvGrid& rGrid = implGetGrid();
1455 ScAccessibleCsvGrid* pAcc = static_cast<ScAccessibleCsvGrid*>(rGrid.GetAccessible());
1457 return pAcc;
1460 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */