1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 // ============================================================================
28 #include "AccessibleCsvControl.hxx"
29 #include <com/sun/star/accessibility/AccessibleRole.hpp>
30 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLERELATIONTYPE_HPP_
31 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
32 #endif
33 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
34 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
35 #endif
36 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
37 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
38 #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
39 #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
40 #include <tools/debug.hxx>
41 #include <rtl/uuid.h>
42 #include <toolkit/helper/convert.hxx>
43 #include <unotools/accessiblerelationsethelper.hxx>
44 #ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
45 #include <unotools/accessiblestatesethelper.hxx>
46 #endif
47 #include <comphelper/sequence.hxx>
48 #include "scitems.hxx"
49 #include <editeng/fontitem.hxx>
50 #include <editeng/fhgtitem.hxx>
51 #include <editeng/langitem.hxx>
52 #include "csvcontrol.hxx"
53 #include "csvruler.hxx"
54 #include "csvgrid.hxx"
55 #include "AccessibleText.hxx"
56 #include "editsrc.hxx"
57 #include "unoguard.hxx"
58 #include "scresid.hxx"
59 #include "sc.hrc"
60 #include "scmod.hxx"
61 #include <svtools/colorcfg.hxx>
62 // ause
63 #include "editutil.hxx"
64 
65 using ::rtl::OUString;
66 using ::rtl::OUStringBuffer;
67 using ::utl::AccessibleRelationSetHelper;
68 using ::utl::AccessibleStateSetHelper;
69 using ::accessibility::AccessibleStaticTextBase;
70 using ::com::sun::star::uno::Any;
71 using ::com::sun::star::uno::Reference;
72 using ::com::sun::star::uno::Sequence;
73 using ::com::sun::star::uno::RuntimeException;
74 using ::com::sun::star::uno::XInterface;
75 using ::com::sun::star::lang::DisposedException;
76 using ::com::sun::star::lang::IndexOutOfBoundsException;
77 using ::com::sun::star::lang::IllegalArgumentException;
78 using ::com::sun::star::beans::PropertyValue;
79 using namespace	::com::sun::star::accessibility;
80 
81 
82 // ----------------------------------------------------------------------------
83 
84 const sal_uInt16 nRulerRole         = AccessibleRole::TEXT;
85 const sal_uInt16 nGridRole          = AccessibleRole::TABLE;
86 const sal_uInt16 nCellRole          = AccessibleRole::TEXT;
87 
88 #define CREATE_OUSTRING( name )     OUString( RTL_CONSTASCII_USTRINGPARAM( name ) )
89 
90 #define RULER_IMPL_NAME             "ScAccessibleCsvRuler"
91 #define GRID_IMPL_NAME              "ScAccessibleCsvGrid"
92 #define CELL_IMPL_NAME              "ScAccessibleCsvCell"
93 
94 const sal_Unicode cRulerDot         = '.';
95 const sal_Unicode cRulerLine        = '|';
96 
97 const sal_Int32 CSV_LINE_HEADER     = CSV_POS_INVALID;
98 const sal_uInt32 CSV_COLUMN_HEADER  = CSV_COLUMN_INVALID;
99 
100 
101 // CSV base control ===========================================================
102 
DBG_NAME(ScAccessibleCsvControl)103 DBG_NAME( ScAccessibleCsvControl )
104 
105 ScAccessibleCsvControl::ScAccessibleCsvControl(
106         const Reference< XAccessible >& rxParent,
107         ScCsvControl& rControl,
108         sal_uInt16 nRole ) :
109     ScAccessibleContextBase( rxParent, nRole ),
110     mpControl( &rControl )
111 {
112     DBG_CTOR( ScAccessibleCsvControl, NULL );
113 }
114 
~ScAccessibleCsvControl()115 ScAccessibleCsvControl::~ScAccessibleCsvControl()
116 {
117     DBG_DTOR( ScAccessibleCsvControl, NULL );
118     implDispose();
119 }
120 
disposing()121 void SAL_CALL ScAccessibleCsvControl::disposing()
122 {
123     ScUnoGuard aGuard;
124     mpControl = NULL;
125     ScAccessibleContextBase::disposing();
126 }
127 
128 
129 // XAccessibleComponent -------------------------------------------------------
130 
getAccessibleAtPoint(const AwtPoint &)131 Reference< XAccessible > SAL_CALL ScAccessibleCsvControl::getAccessibleAtPoint( const AwtPoint& /* rPoint */ )
132         throw( RuntimeException )
133 {
134     ensureAlive();
135     return NULL;
136 }
137 
isVisible()138 sal_Bool SAL_CALL ScAccessibleCsvControl::isVisible() throw( RuntimeException )
139 {
140     ScUnoGuard aGuard;
141     ensureAlive();
142     return implGetControl().IsVisible();
143 }
144 
grabFocus()145 void SAL_CALL ScAccessibleCsvControl::grabFocus() throw( RuntimeException )
146 {
147     ScUnoGuard aGuard;
148     ensureAlive();
149     implGetControl().GrabFocus();
150 }
151 
152 
153 // events ---------------------------------------------------------------------
154 
SendFocusEvent(bool bFocused)155 void ScAccessibleCsvControl::SendFocusEvent( bool bFocused )
156 {
157     if( bFocused )
158         CommitFocusGained();
159     else
160         CommitFocusLost();
161 }
162 
SendCaretEvent()163 void ScAccessibleCsvControl::SendCaretEvent()
164 {
165     DBG_ERRORFILE( "ScAccessibleCsvControl::SendCaretEvent - Illegal call" );
166 }
167 
SendVisibleEvent()168 void ScAccessibleCsvControl::SendVisibleEvent()
169 {
170     AccessibleEventObject aEvent;
171     aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
172     aEvent.Source = Reference< XAccessible >( this );
173     CommitChange( aEvent );
174 }
175 
SendSelectionEvent()176 void ScAccessibleCsvControl::SendSelectionEvent()
177 {
178     AccessibleEventObject aEvent;
179     aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
180     aEvent.Source = Reference< XAccessible >( this );
181     CommitChange( aEvent );
182 }
183 
SendTableUpdateEvent(sal_uInt32,sal_uInt32,bool)184 void ScAccessibleCsvControl::SendTableUpdateEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */, bool /* bAllRows */ )
185 {
186     DBG_ERRORFILE( "ScAccessibleCsvControl::SendTableUpdateEvent - Illegal call" );
187 }
188 
SendInsertColumnEvent(sal_uInt32,sal_uInt32)189 void ScAccessibleCsvControl::SendInsertColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ )
190 {
191     DBG_ERRORFILE( "ScAccessibleCsvControl::SendInsertColumnEvent - Illegal call" );
192 }
193 
SendRemoveColumnEvent(sal_uInt32,sal_uInt32)194 void ScAccessibleCsvControl::SendRemoveColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ )
195 {
196     DBG_ERRORFILE( "ScAccessibleCsvControl::SendRemoveColumnEvent - Illegal call" );
197 }
198 
199 
200 // helpers --------------------------------------------------------------------
201 
GetBoundingBoxOnScreen() const202 Rectangle ScAccessibleCsvControl::GetBoundingBoxOnScreen() const throw( RuntimeException )
203 {
204     ScUnoGuard aGuard;
205     ensureAlive();
206     return implGetControl().GetWindowExtentsRelative( NULL );
207 }
208 
GetBoundingBox() const209 Rectangle ScAccessibleCsvControl::GetBoundingBox() const throw( RuntimeException )
210 {
211     ScUnoGuard aGuard;
212     ensureAlive();
213     return implGetControl().GetWindowExtentsRelative( implGetControl().GetAccessibleParentWindow() );
214 }
215 
getUuid(Sequence<sal_Int8> & rSeq)216 void ScAccessibleCsvControl::getUuid( Sequence< sal_Int8 >& rSeq )
217 {
218     ScUnoGuard aGuard;
219     ensureAlive();
220     if( !rSeq.hasElements() )
221     {
222         rSeq.realloc( 16 );
223         rtl_createUuid( reinterpret_cast< sal_uInt8* >( rSeq.getArray() ), NULL, sal_True );
224     }
225 }
226 
ensureAlive() const227 void ScAccessibleCsvControl::ensureAlive() const throw( DisposedException )
228 {
229     if( !implIsAlive() )
230         throw DisposedException();
231 }
232 
implGetControl() const233 ScCsvControl& ScAccessibleCsvControl::implGetControl() const
234 {
235     DBG_ASSERT( mpControl, "ScAccessibleCsvControl::implGetControl - missing control" );
236     return *mpControl;
237 }
238 
implGetChildByRole(const Reference<XAccessible> & rxParentObj,sal_uInt16 nRole)239 Reference< XAccessible > ScAccessibleCsvControl::implGetChildByRole(
240         const Reference< XAccessible >& rxParentObj, sal_uInt16 nRole ) throw( RuntimeException )
241 {
242     Reference< XAccessible > xAccObj;
243     if( rxParentObj.is() )
244     {
245         Reference< XAccessibleContext > xParentCtxt = rxParentObj->getAccessibleContext();
246         if( xParentCtxt.is() )
247         {
248             sal_Int32 nCount = xParentCtxt->getAccessibleChildCount();
249             sal_Int32 nIndex = 0;
250             while( !xAccObj.is() && (nIndex < nCount) )
251             {
252                 Reference< XAccessible > xCurrObj = xParentCtxt->getAccessibleChild( nIndex );
253                 if( xCurrObj.is() )
254                 {
255                     Reference< XAccessibleContext > xCurrCtxt = xCurrObj->getAccessibleContext();
256                     if( xCurrCtxt.is() && (xCurrCtxt->getAccessibleRole() == nRole) )
257                         xAccObj = xCurrObj;
258                 }
259                 ++nIndex;
260             }
261         }
262     }
263     return xAccObj;
264 }
265 
implCreateStateSet()266 AccessibleStateSetHelper* ScAccessibleCsvControl::implCreateStateSet()
267 {
268     ScUnoGuard aGuard;
269     AccessibleStateSetHelper* pStateSet = new AccessibleStateSetHelper();
270     if( implIsAlive() )
271     {
272         const ScCsvControl& rCtrl = implGetControl();
273         pStateSet->AddState( AccessibleStateType::OPAQUE );
274         if( rCtrl.IsEnabled() )
275             pStateSet->AddState( AccessibleStateType::ENABLED );
276         if( isShowing() )
277             pStateSet->AddState( AccessibleStateType::SHOWING );
278         if( isVisible() )
279             pStateSet->AddState( AccessibleStateType::VISIBLE );
280     }
281     else
282         pStateSet->AddState( AccessibleStateType::DEFUNC );
283     return pStateSet;
284 }
285 
implDispose()286 void ScAccessibleCsvControl::implDispose()
287 {
288     if( implIsAlive() )
289     {
290         // prevent multiple call of dtor
291         osl_incrementInterlockedCount( &m_refCount );
292         dispose();
293     }
294 }
295 
implGetAbsPos(const Point & rPos) const296 Point ScAccessibleCsvControl::implGetAbsPos( const Point& rPos ) const
297 {
298     return rPos + implGetControl().GetWindowExtentsRelative( NULL ).TopLeft();
299 }
300 
301 
302 // Ruler ======================================================================
303 
304 /** Converts a ruler cursor position to API text index. */
lcl_GetApiPos(sal_Int32 nRulerPos)305 sal_Int32 lcl_GetApiPos( sal_Int32 nRulerPos )
306 {
307     sal_Int32 nApiPos = nRulerPos;
308     sal_Int32 nStart = (nRulerPos - 1) / 10;
309     sal_Int32 nExp = 1;
310     while( nStart >= nExp )
311     {
312         nApiPos += nStart - nExp + 1;
313         nExp *= 10;
314     }
315     return ::std::max( nApiPos, static_cast<sal_Int32>(0) );
316 }
317 
318 /** Converts an API text index to a ruler cursor position. */
lcl_GetRulerPos(sal_Int32 nApiPos)319 sal_Int32 lcl_GetRulerPos( sal_Int32 nApiPos )
320 {
321     sal_Int32 nDiv = 10;
322     sal_Int32 nExp = 10;
323     sal_Int32 nRulerPos = 0;
324     sal_Int32 nApiBase = 0;
325     sal_Int32 nApiLimit = 10;
326     while( nApiPos >= nApiLimit )
327     {
328         ++nDiv;
329         nRulerPos = nExp;
330         nExp *= 10;
331         nApiBase = nApiLimit;
332         nApiLimit = lcl_GetApiPos( nExp );
333     }
334     sal_Int32 nRelPos = nApiPos - nApiBase;
335     return nRulerPos + nRelPos / nDiv * 10 + ::std::max( nRelPos % nDiv - nDiv + 10L, 0L );
336 }
337 
338 /** Expands the sequence's size and returns the base index of the new inserted elements. */
lcl_ExpandSequence(Sequence<PropertyValue> & rSeq,sal_Int32 nExp)339 inline sal_Int32 lcl_ExpandSequence( Sequence< PropertyValue >& rSeq, sal_Int32 nExp )
340 {
341     DBG_ASSERT( nExp > 0, "lcl_ExpandSequence - invalid value" );
342     rSeq.realloc( rSeq.getLength() + nExp );
343     return rSeq.getLength() - nExp;
344 }
345 
346 /** Fills the property value rVal with the specified name and value from the item. */
lcl_FillProperty(PropertyValue & rVal,const OUString & rPropName,const SfxPoolItem & rItem,sal_uInt8 nMID)347 inline void lcl_FillProperty( PropertyValue& rVal, const OUString& rPropName, const SfxPoolItem& rItem, sal_uInt8 nMID )
348 {
349     rVal.Name = rPropName;
350     rItem.QueryValue( rVal.Value, nMID );
351 }
352 
353 /** Fills the sequence with all font attributes of rFont. */
lcl_FillFontAttributes(Sequence<PropertyValue> & rSeq,const Font & rFont)354 void lcl_FillFontAttributes( Sequence< PropertyValue >& rSeq, const Font& rFont )
355 {
356     SvxFontItem aFontItem( rFont.GetFamily(), rFont.GetName(), rFont.GetStyleName(), rFont.GetPitch(), rFont.GetCharSet(), ATTR_FONT );
357     SvxFontHeightItem aHeightItem( rFont.GetSize().Height(), 100, ATTR_FONT_HEIGHT );
358     SvxLanguageItem aLangItem( rFont.GetLanguage(), ATTR_FONT_LANGUAGE );
359 
360     sal_Int32 nIndex = lcl_ExpandSequence( rSeq, 7 );
361     lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontName" ),      aFontItem,   MID_FONT_FAMILY_NAME );
362     lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontFamily" ),    aFontItem,   MID_FONT_FAMILY );
363     lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontStyleName" ), aFontItem,   MID_FONT_STYLE_NAME );
364     lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontCharSet" ),   aFontItem,   MID_FONT_PITCH );
365     lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontPitch" ),     aFontItem,   MID_FONT_CHAR_SET );
366     lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharHeight" ),        aHeightItem, MID_FONTHEIGHT );
367     lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharLocale" ),        aLangItem,   MID_LANG_LOCALE );
368 }
369 
370 
371 
372 // ----------------------------------------------------------------------------
373 
DBG_NAME(ScAccessibleCsvRuler)374 DBG_NAME( ScAccessibleCsvRuler )
375 
376 ScAccessibleCsvRuler::ScAccessibleCsvRuler( ScCsvRuler& rRuler ) :
377     ScAccessibleCsvControl( rRuler.GetAccessibleParentWindow()->GetAccessible(), rRuler, nRulerRole )
378 {
379     DBG_CTOR( ScAccessibleCsvRuler, NULL );
380     constructStringBuffer();
381 }
382 
~ScAccessibleCsvRuler()383 ScAccessibleCsvRuler::~ScAccessibleCsvRuler()
384 {
385     DBG_DTOR( ScAccessibleCsvRuler, NULL );
386     implDispose();
387 }
388 
389 // XAccessibleComponent -----------------------------------------------------
390 
getForeground()391 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getForeground(  )
392     throw (RuntimeException)
393 {
394     ScUnoGuard aGuard;
395     ensureAlive();
396     return implGetRuler().GetSettings().GetStyleSettings().GetLabelTextColor().GetColor();
397 }
398 
getBackground()399 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getBackground(  )
400     throw (RuntimeException)
401 {
402     ScUnoGuard aGuard;
403     ensureAlive();
404     return implGetRuler().GetSettings().GetStyleSettings().GetFaceColor().GetColor();
405 }
406 
407 // XAccessibleContext ---------------------------------------------------------
408 
getAccessibleChildCount()409 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getAccessibleChildCount() throw( RuntimeException )
410 {
411     ensureAlive();
412     return 0;
413 }
414 
getAccessibleChild(sal_Int32)415 Reference< XAccessible > SAL_CALL ScAccessibleCsvRuler::getAccessibleChild( sal_Int32 /* nIndex */ )
416         throw( IndexOutOfBoundsException, RuntimeException )
417 {
418     ensureAlive();
419     throw IndexOutOfBoundsException();
420 }
421 
getAccessibleRelationSet()422 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvRuler::getAccessibleRelationSet()
423         throw( RuntimeException )
424 {
425     ScUnoGuard aGuard;
426     ensureAlive();
427     AccessibleRelationSetHelper* pRelationSet = new AccessibleRelationSetHelper();
428     Reference< XAccessible > xAccObj = implGetChildByRole( getAccessibleParent(), nGridRole );
429     if( xAccObj.is() )
430     {
431         Sequence< Reference< XInterface > > aSeq( 1 );
432         aSeq[ 0 ] = xAccObj;
433         pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::CONTROLLER_FOR, aSeq ) );
434     }
435     return pRelationSet;
436 }
437 
getAccessibleStateSet()438 Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvRuler::getAccessibleStateSet()
439         throw( RuntimeException )
440 {
441     ScUnoGuard aGuard;
442     AccessibleStateSetHelper* pStateSet = implCreateStateSet();
443     if( implIsAlive() )
444     {
445         pStateSet->AddState( AccessibleStateType::FOCUSABLE );
446         pStateSet->AddState( AccessibleStateType::SINGLE_LINE );
447         if( implGetRuler().HasFocus() )
448             pStateSet->AddState( AccessibleStateType::FOCUSED );
449     }
450     return pStateSet;
451 }
452 
453 
454 // XAccessibleText ------------------------------------------------------------
455 
getCaretPosition()456 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCaretPosition() throw( RuntimeException )
457 {
458     ScUnoGuard aGuard;
459     ensureAlive();
460     return lcl_GetApiPos( implGetRuler().GetRulerCursorPos() );
461 }
462 
setCaretPosition(sal_Int32 nIndex)463 sal_Bool SAL_CALL ScAccessibleCsvRuler::setCaretPosition( sal_Int32 nIndex )
464         throw( IndexOutOfBoundsException, RuntimeException )
465 {
466     ScUnoGuard aGuard;
467     ensureAlive();
468     ensureValidIndex( nIndex );
469     ScCsvRuler& rRuler = implGetRuler();
470     sal_Int32 nOldCursor = rRuler.GetRulerCursorPos();
471     rRuler.Execute( CSVCMD_MOVERULERCURSOR, lcl_GetRulerPos( nIndex ) );
472     return rRuler.GetRulerCursorPos() != nOldCursor;
473 }
474 
getCharacter(sal_Int32 nIndex)475 sal_Unicode SAL_CALL ScAccessibleCsvRuler::getCharacter( sal_Int32 nIndex )
476         throw( IndexOutOfBoundsException, RuntimeException )
477 {
478     ScUnoGuard aGuard;
479     ensureAlive();
480     ensureValidIndex( nIndex );
481     return maBuffer.charAt( nIndex );
482 }
483 
getCharacterAttributes(sal_Int32 nIndex,const::com::sun::star::uno::Sequence<::rtl::OUString> &)484 Sequence< PropertyValue > SAL_CALL ScAccessibleCsvRuler::getCharacterAttributes( sal_Int32 nIndex,
485             const ::com::sun::star::uno::Sequence< ::rtl::OUString >& /* aRequestedAttributes */ )
486         throw( IndexOutOfBoundsException, RuntimeException )
487 {
488     ScUnoGuard aGuard;
489     ensureAlive();
490     ensureValidIndexWithEnd( nIndex );
491     Sequence< PropertyValue > aSeq;
492     lcl_FillFontAttributes( aSeq, implGetRuler().GetFont() );
493 //! TODO split attribute: waiting for #102221#
494 //    if( implHasSplit( nIndex ) )
495 //    {
496 //        sal_Int32 nIndex = lcl_ExpandSequence( aSeq, 1 );
497 //        aSeq[ nIndex ].Name = CREATE_OUSTRING( "..." );
498 //        aSeq[ nIndex ].Value <<= ...;
499 //    }
500     return aSeq;
501 }
502 
getCharacterBounds(sal_Int32 nIndex)503 ScAccessibleCsvRuler::AwtRectangle SAL_CALL ScAccessibleCsvRuler::getCharacterBounds( sal_Int32 nIndex )
504         throw( IndexOutOfBoundsException, RuntimeException )
505 {
506     ScUnoGuard aGuard;
507     ensureAlive();
508     ensureValidIndexWithEnd( nIndex );
509     ScCsvRuler& rRuler = implGetRuler();
510     Point aPos( rRuler.GetX( lcl_GetRulerPos( nIndex ) ) - rRuler.GetCharWidth() / 2, 0 );
511     AwtRectangle aRect( aPos.X(), aPos.Y(), rRuler.GetCharWidth(), rRuler.GetSizePixel().Height() );
512     // #107054# do not return rectangle out of window
513     sal_Int32 nWidth = rRuler.GetOutputSizePixel().Width();
514     if( aRect.X >= nWidth )
515         throw IndexOutOfBoundsException();
516     if( aRect.X + aRect.Width > nWidth )
517         aRect.Width = nWidth - aRect.X;
518     return aRect;
519 }
520 
getCharacterCount()521 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCharacterCount() throw( RuntimeException )
522 {
523     ScUnoGuard aGuard;
524     ensureAlive();
525     return implGetTextLength();
526 }
527 
getIndexAtPoint(const AwtPoint & rPoint)528 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getIndexAtPoint( const AwtPoint& rPoint )
529         throw( RuntimeException )
530 {
531     ScUnoGuard aGuard;
532     ensureAlive();
533     ScCsvRuler& rRuler = implGetRuler();
534     // #107054# use object's coordinate system, convert to API position
535     return lcl_GetApiPos( ::std::min( ::std::max( rRuler.GetPosFromX( rPoint.X ), static_cast<sal_Int32>(0) ), rRuler.GetPosCount() ) );
536 }
537 
getSelectedText()538 OUString SAL_CALL ScAccessibleCsvRuler::getSelectedText() throw( RuntimeException )
539 {
540     ensureAlive();
541     return OUString();
542 }
543 
getSelectionStart()544 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionStart() throw( RuntimeException )
545 {
546     ensureAlive();
547     return -1;
548 }
549 
getSelectionEnd()550 sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionEnd() throw( RuntimeException )
551 {
552     ensureAlive();
553     return -1;
554 }
555 
setSelection(sal_Int32,sal_Int32)556 sal_Bool SAL_CALL ScAccessibleCsvRuler::setSelection( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ )
557         throw( IndexOutOfBoundsException, RuntimeException )
558 {
559     ensureAlive();
560     return sal_False;
561 }
562 
getText()563 OUString SAL_CALL ScAccessibleCsvRuler::getText() throw( RuntimeException )
564 {
565     ScUnoGuard aGuard;
566     ensureAlive();
567     return OUString( maBuffer.getStr(), implGetTextLength() );
568 }
569 
getTextRange(sal_Int32 nStartIndex,sal_Int32 nEndIndex)570 OUString SAL_CALL ScAccessibleCsvRuler::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
571         throw( IndexOutOfBoundsException, RuntimeException )
572 {
573     ScUnoGuard aGuard;
574     ensureAlive();
575     ensureValidRange( nStartIndex, nEndIndex );
576     return OUString( maBuffer.getStr() + nStartIndex, nEndIndex - nStartIndex );
577 }
578 
getTextAtIndex(sal_Int32 nIndex,sal_Int16 nTextType)579 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextAtIndex( sal_Int32 nIndex, sal_Int16 nTextType )
580         throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException )
581 {
582     ScUnoGuard aGuard;
583     ensureAlive();
584 
585     TextSegment aResult;
586     aResult.SegmentStart = -1;
587     aResult.SegmentEnd = -1;
588 
589     if( (nIndex == implGetTextLength()) && (nTextType != AccessibleTextType::LINE) )
590         return aResult;
591 
592     ensureValidIndex( nIndex );
593 
594     OUStringBuffer aResultText;     // will be assigned to aResult.SegmentText below
595     sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
596 
597     switch( nTextType )
598     {
599         // single character
600         case AccessibleTextType::CHARACTER:
601         {
602             aResult.SegmentStart = nIndex;
603             aResultText.append( maBuffer.charAt( nIndex ) );
604         }
605         break;
606 
607         // entire number or single dot/line
608         case AccessibleTextType::WORD:
609         case AccessibleTextType::GLYPH:
610             aResult.SegmentStart = nIndex;
611             if( nRulerPos % 10 )
612                 aResultText.append( maBuffer.charAt( nIndex ) );
613             else
614                 aResultText.append( nRulerPos );    // string representation of sal_Int32!!!
615         break;
616 
617         // entire text
618         case AccessibleTextType::SENTENCE:
619         case AccessibleTextType::PARAGRAPH:
620         case AccessibleTextType::LINE:
621             aResult.SegmentStart = 0;
622             aResultText.append( maBuffer.getStr(), implGetTextLength() );
623         break;
624 
625         // equal-formatted text
626         case AccessibleTextType::ATTRIBUTE_RUN:
627         {
628             sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex );
629             sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex );
630             aResult.SegmentStart = nFirstIndex;
631             aResultText.append( maBuffer.getStr() + nFirstIndex, nLastIndex - nFirstIndex + 1 );
632         }
633         break;
634 
635         default:
636             throw RuntimeException();
637     }
638 
639     aResult.SegmentText = aResultText.makeStringAndClear();
640     aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
641     return aResult;
642 }
643 
getTextBeforeIndex(sal_Int32 nIndex,sal_Int16 nTextType)644 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 nTextType )
645         throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException )
646 {
647     ScUnoGuard aGuard;
648     ensureAlive();
649     ensureValidIndexWithEnd( nIndex );
650 
651     TextSegment aResult;
652     aResult.SegmentStart = -1;
653     aResult.SegmentEnd = -1;
654 
655     sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
656 
657     switch( nTextType )
658     {
659         // single character
660         case AccessibleTextType::CHARACTER:
661             if( nIndex > 0 )
662                 aResult = getTextAtIndex( nIndex - 1, nTextType );
663             // else empty
664         break;
665 
666         // entire number or single dot/line
667         case AccessibleTextType::WORD:
668         case AccessibleTextType::GLYPH:
669             if( nRulerPos > 0 )
670                 aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos - 1 ), nTextType );
671             // else empty
672         break;
673 
674         // entire text
675         case AccessibleTextType::SENTENCE:
676         case AccessibleTextType::PARAGRAPH:
677         case AccessibleTextType::LINE:
678             // empty
679         break;
680 
681         // equal-formatted text
682         case AccessibleTextType::ATTRIBUTE_RUN:
683         {
684             sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex );
685             if( nFirstIndex > 0 )
686                 aResult = getTextAtIndex( nFirstIndex - 1, nTextType );
687             // else empty
688         }
689         break;
690 
691         default:
692             throw RuntimeException();
693     }
694     return aResult;
695 }
696 
getTextBehindIndex(sal_Int32 nIndex,sal_Int16 nTextType)697 TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 nTextType )
698         throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException )
699 {
700     ScUnoGuard aGuard;
701     ensureAlive();
702     ensureValidIndexWithEnd( nIndex );
703 
704     TextSegment aResult;
705     aResult.SegmentStart = -1;
706     aResult.SegmentEnd = -1;
707 
708     sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
709     sal_Int32 nLastValid = implGetTextLength();
710 
711     switch( nTextType )
712     {
713         // single character
714         case AccessibleTextType::CHARACTER:
715             if( nIndex < nLastValid )
716                 aResult = getTextAtIndex( nIndex + 1, nTextType );
717             // else empty
718         break;
719 
720         // entire number or single dot/line
721         case AccessibleTextType::WORD:
722         case AccessibleTextType::GLYPH:
723             if( nRulerPos < implGetRuler().GetPosCount() )
724                 aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos + 1 ), nTextType );
725             // else empty
726         break;
727 
728         // entire text
729         case AccessibleTextType::SENTENCE:
730         case AccessibleTextType::PARAGRAPH:
731         case AccessibleTextType::LINE:
732             // empty
733         break;
734 
735         // equal-formatted text
736         case AccessibleTextType::ATTRIBUTE_RUN:
737         {
738             sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex );
739             if( nLastIndex < nLastValid )
740                 aResult = getTextAtIndex( nLastIndex + 1, nTextType );
741             // else empty
742         }
743         break;
744 
745         default:
746             throw RuntimeException();
747     }
748     return aResult;
749 }
750 
copyText(sal_Int32,sal_Int32)751 sal_Bool SAL_CALL ScAccessibleCsvRuler::copyText( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ )
752         throw( IndexOutOfBoundsException, RuntimeException )
753 {
754     ensureAlive();
755     return sal_False;
756 }
757 
758 
759 // XInterface -----------------------------------------------------------------
760 
queryInterface(const::com::sun::star::uno::Type & rType)761 Any SAL_CALL ScAccessibleCsvRuler::queryInterface( const ::com::sun::star::uno::Type& rType )
762         throw( RuntimeException )
763 {
764     Any aAny( ScAccessibleCsvRulerImpl::queryInterface( rType ) );
765     return aAny.hasValue() ? aAny : ScAccessibleCsvControl::queryInterface( rType );
766 }
767 
acquire()768 void SAL_CALL ScAccessibleCsvRuler::acquire() throw ()
769 {
770     ScAccessibleCsvControl::acquire();
771 }
772 
release()773 void SAL_CALL ScAccessibleCsvRuler::release() throw ()
774 {
775     ScAccessibleCsvControl::release();
776 }
777 
778 
779 // XServiceInfo ---------------------------------------------------------------
780 
getImplementationName()781 OUString SAL_CALL ScAccessibleCsvRuler::getImplementationName() throw( RuntimeException )
782 {
783     return CREATE_OUSTRING( RULER_IMPL_NAME );
784 }
785 
786 
787 // XTypeProvider --------------------------------------------------------------
788 
getTypes()789 Sequence< ::com::sun::star::uno::Type > SAL_CALL ScAccessibleCsvRuler::getTypes() throw( RuntimeException )
790 {
791     Sequence< ::com::sun::star::uno::Type > aSeq( 1 );
792     aSeq[ 0 ] = getCppuType( static_cast< const Reference< XAccessibleText >* >( NULL ) );
793     return ::comphelper::concatSequences( ScAccessibleCsvControl::getTypes(), aSeq );
794 }
795 
getImplementationId()796 Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvRuler::getImplementationId() throw( RuntimeException )
797 {
798     static Sequence< sal_Int8 > aSeq;
799     getUuid( aSeq );
800     return aSeq;
801 }
802 
803 
804 // events ---------------------------------------------------------------------
805 
SendCaretEvent()806 void ScAccessibleCsvRuler::SendCaretEvent()
807 {
808     sal_Int32 nPos = implGetRuler().GetRulerCursorPos();
809     if( nPos != CSV_POS_INVALID )
810     {
811         AccessibleEventObject aEvent;
812         aEvent.EventId = AccessibleEventId::CARET_CHANGED;
813         aEvent.Source = Reference< XAccessible >( this );
814         aEvent.NewValue <<= nPos;
815         CommitChange( aEvent );
816     }
817 }
818 
819 
820 // helpers --------------------------------------------------------------------
821 
createAccessibleName()822 OUString SAL_CALL ScAccessibleCsvRuler::createAccessibleName() throw( RuntimeException )
823 {
824     return String( ScResId( STR_ACC_CSVRULER_NAME ) );
825 }
826 
createAccessibleDescription()827 OUString SAL_CALL ScAccessibleCsvRuler::createAccessibleDescription() throw( RuntimeException )
828 {
829     return String( ScResId( STR_ACC_CSVRULER_DESCR ) );
830 }
831 
ensureValidIndex(sal_Int32 nIndex) const832 void ScAccessibleCsvRuler::ensureValidIndex( sal_Int32 nIndex ) const
833         throw( IndexOutOfBoundsException )
834 {
835     if( (nIndex < 0) || (nIndex >= implGetTextLength()) )
836         throw IndexOutOfBoundsException();
837 }
838 
ensureValidIndexWithEnd(sal_Int32 nIndex) const839 void ScAccessibleCsvRuler::ensureValidIndexWithEnd( sal_Int32 nIndex ) const
840         throw( IndexOutOfBoundsException )
841 {
842     if( (nIndex < 0) || (nIndex > implGetTextLength()) )
843         throw IndexOutOfBoundsException();
844 }
845 
ensureValidRange(sal_Int32 & rnStartIndex,sal_Int32 & rnEndIndex) const846 void ScAccessibleCsvRuler::ensureValidRange( sal_Int32& rnStartIndex, sal_Int32& rnEndIndex ) const
847         throw( IndexOutOfBoundsException )
848 {
849     if( rnStartIndex > rnEndIndex )
850         ::std::swap( rnStartIndex, rnEndIndex );
851     if( (rnStartIndex < 0) || (rnEndIndex > implGetTextLength()) )
852         throw IndexOutOfBoundsException();
853 }
854 
implGetRuler() const855 ScCsvRuler& ScAccessibleCsvRuler::implGetRuler() const
856 {
857     return static_cast< ScCsvRuler& >( implGetControl() );
858 }
859 
constructStringBuffer()860 void ScAccessibleCsvRuler::constructStringBuffer() throw( RuntimeException )
861 {
862     ScUnoGuard aGuard;
863     ensureAlive();
864     // extend existing string buffer to new ruler size
865     sal_Int32 nRulerCount = implGetRuler().GetPosCount();
866     sal_Int32 nRulerPos = lcl_GetRulerPos( maBuffer.getLength() );
867     for( ; nRulerPos <= nRulerCount; ++nRulerPos ) // include last position
868     {
869         switch( nRulerPos % 10 )
870         {
871             case 0:     maBuffer.append( nRulerPos );   break;
872             case 5:     maBuffer.append( cRulerLine );  break;
873             default:    maBuffer.append( cRulerDot );
874         }
875     }
876 }
877 
implGetTextLength() const878 sal_Int32 ScAccessibleCsvRuler::implGetTextLength() const
879 {
880     return lcl_GetApiPos( implGetRuler().GetPosCount() + 1 );
881 }
882 
implHasSplit(sal_Int32 nApiPos)883 bool ScAccessibleCsvRuler::implHasSplit( sal_Int32 nApiPos )
884 {
885     sal_Int32 nRulerPos = lcl_GetRulerPos( nApiPos );
886     return implGetRuler().HasSplit( nRulerPos ) && (nApiPos == lcl_GetApiPos( nRulerPos ));
887 }
888 
implGetFirstEqualFormatted(sal_Int32 nApiPos)889 sal_Int32 ScAccessibleCsvRuler::implGetFirstEqualFormatted( sal_Int32 nApiPos )
890 {
891     bool bSplit = implHasSplit( nApiPos );
892     while( (nApiPos > 0) && (implHasSplit( nApiPos - 1 ) == bSplit) )
893         --nApiPos;
894     return nApiPos;
895 }
896 
implGetLastEqualFormatted(sal_Int32 nApiPos)897 sal_Int32 ScAccessibleCsvRuler::implGetLastEqualFormatted( sal_Int32 nApiPos )
898 {
899     bool bSplit = implHasSplit( nApiPos );
900     sal_Int32 nLength = implGetTextLength();
901     while( (nApiPos < nLength - 1) && (implHasSplit( nApiPos + 1 ) == bSplit) )
902         ++nApiPos;
903     return nApiPos;
904 }
905 
906 
907 // Grid =======================================================================
908 
909 /** Converts a grid columnm index to an API column index. */
lcl_GetApiColumn(sal_uInt32 nGridColumn)910 inline sal_Int32 lcl_GetApiColumn( sal_uInt32 nGridColumn )
911 {
912     return (nGridColumn != CSV_COLUMN_HEADER) ? static_cast< sal_Int32 >( nGridColumn + 1 ) : 0;
913 }
914 
915 /** Converts an API columnm index to a ScCsvGrid column index. */
lcl_GetGridColumn(sal_Int32 nApiColumn)916 inline sal_uInt32 lcl_GetGridColumn( sal_Int32 nApiColumn )
917 {
918     return (nApiColumn > 0) ? static_cast< sal_uInt32 >( nApiColumn - 1 ) : CSV_COLUMN_HEADER;
919 }
920 
921 
922 // ----------------------------------------------------------------------------
923 
DBG_NAME(ScAccessibleCsvGrid)924 DBG_NAME( ScAccessibleCsvGrid )
925 
926 ScAccessibleCsvGrid::ScAccessibleCsvGrid( ScCsvGrid& rGrid ) :
927     ScAccessibleCsvControl( rGrid.GetAccessibleParentWindow()->GetAccessible(), rGrid, nGridRole )
928 {
929     DBG_CTOR( ScAccessibleCsvGrid, NULL );
930 }
931 
~ScAccessibleCsvGrid()932 ScAccessibleCsvGrid::~ScAccessibleCsvGrid()
933 {
934     DBG_DTOR( ScAccessibleCsvGrid, NULL );
935     implDispose();
936 }
937 
938 
939 // XAccessibleComponent -------------------------------------------------------
940 
getAccessibleAtPoint(const AwtPoint & rPoint)941 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleAtPoint( const AwtPoint& rPoint )
942         throw( RuntimeException )
943 {
944     Reference< XAccessible > xRet;
945     if( containsPoint( rPoint ) )
946     {
947         ScUnoGuard aGuard;
948         ensureAlive();
949 
950         const ScCsvGrid& rGrid = implGetGrid();
951         // #102679#; use <= instead of <, because the offset is the size and not the point
952         sal_Int32 nColumn = ((rGrid.GetFirstX() <= rPoint.X) && (rPoint.X <= rGrid.GetLastX())) ?
953             lcl_GetApiColumn( rGrid.GetColumnFromX( rPoint.X ) ) : 0;
954         sal_Int32 nRow = (rPoint.Y >= rGrid.GetHdrHeight()) ?
955             (rGrid.GetLineFromY( rPoint.Y ) - rGrid.GetFirstVisLine() + 1) : 0;
956         xRet = implCreateCellObj( nRow, nColumn );
957     }
958     return xRet;
959 }
960 
getForeground()961 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getForeground(  )
962 throw (RuntimeException)
963 {
964     ScUnoGuard aGuard;
965     ensureAlive();
966     return implGetGrid().GetSettings().GetStyleSettings().GetButtonTextColor().GetColor();
967 }
968 
getBackground()969 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getBackground(  )
970 throw (RuntimeException)
971 {
972     ScUnoGuard aGuard;
973     ensureAlive();
974     return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
975 }
976 
977 // XAccessibleContext ---------------------------------------------------------
978 
getAccessibleChildCount()979 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleChildCount() throw( RuntimeException )
980 {
981     ScUnoGuard aGuard;
982     ensureAlive();
983     return implGetCellCount();
984 }
985 
getAccessibleChild(sal_Int32 nIndex)986 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleChild( sal_Int32 nIndex )
987         throw( IndexOutOfBoundsException, RuntimeException )
988 {
989     ScUnoGuard aGuard;
990     ensureAlive();
991     ensureValidIndex( nIndex );
992     return implCreateCellObj( implGetRow( nIndex ), implGetColumn( nIndex ) );
993 }
994 
getAccessibleRelationSet()995 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleRelationSet()
996         throw( RuntimeException )
997 {
998     ScUnoGuard aGuard;
999     ensureAlive();
1000     AccessibleRelationSetHelper* pRelationSet = new AccessibleRelationSetHelper();
1001     Reference< XAccessible > xAccObj = implGetChildByRole( getAccessibleParent(), nRulerRole );
1002     if( xAccObj.is() )
1003     {
1004         Sequence< Reference< XInterface > > aSeq( 1 );
1005         aSeq[ 0 ] = xAccObj;
1006         pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::CONTROLLED_BY, aSeq ) );
1007     }
1008     return pRelationSet;
1009 }
1010 
getAccessibleStateSet()1011 Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleStateSet()
1012         throw( RuntimeException )
1013 {
1014     ScUnoGuard aGuard;
1015     AccessibleStateSetHelper* pStateSet = implCreateStateSet();
1016     if( implIsAlive() )
1017     {
1018         pStateSet->AddState( AccessibleStateType::FOCUSABLE );
1019         pStateSet->AddState( AccessibleStateType::MULTI_SELECTABLE );
1020         pStateSet->AddState( AccessibleStateType::MANAGES_DESCENDANTS );
1021         if( implGetGrid().HasFocus() )
1022             pStateSet->AddState( AccessibleStateType::FOCUSED );
1023     }
1024     else
1025         pStateSet->AddState( AccessibleStateType::DEFUNC );
1026     return pStateSet;
1027 }
1028 
1029 
1030 // XAccessibleTable -----------------------------------------------------------
1031 
getAccessibleRowCount()1032 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowCount() throw( RuntimeException )
1033 {
1034     ScUnoGuard aGuard;
1035     ensureAlive();
1036     return implGetRowCount();
1037 }
1038 
getAccessibleColumnCount()1039 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnCount() throw( RuntimeException )
1040 {
1041     ScUnoGuard aGuard;
1042     ensureAlive();
1043     return implGetColumnCount();
1044 }
1045 
getAccessibleRowDescription(sal_Int32 nRow)1046 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleRowDescription( sal_Int32 nRow )
1047         throw( IndexOutOfBoundsException, RuntimeException )
1048 {
1049     ScUnoGuard aGuard;
1050     ensureAlive();
1051     ensureValidPosition( nRow, 0 );
1052     return implGetCellText( nRow, 0 );
1053 }
1054 
getAccessibleColumnDescription(sal_Int32 nColumn)1055 OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnDescription( sal_Int32 nColumn )
1056         throw( IndexOutOfBoundsException, RuntimeException )
1057 {
1058     ScUnoGuard aGuard;
1059     ensureAlive();
1060     ensureValidPosition( 0, nColumn );
1061     return implGetCellText( 0, nColumn );
1062 }
1063 
getAccessibleRowExtentAt(sal_Int32 nRow,sal_Int32 nColumn)1064 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
1065         throw( IndexOutOfBoundsException, RuntimeException )
1066 {
1067     ensureAlive();
1068     ensureValidPosition( nRow, nColumn );
1069     return 1;
1070 }
1071 
getAccessibleColumnExtentAt(sal_Int32 nRow,sal_Int32 nColumn)1072 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
1073         throw( IndexOutOfBoundsException, RuntimeException )
1074 {
1075     ensureAlive();
1076     ensureValidPosition( nRow, nColumn );
1077     return 1;
1078 }
1079 
getAccessibleRowHeaders()1080 Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleRowHeaders()
1081         throw( RuntimeException )
1082 {
1083     ensureAlive();
1084     return NULL;
1085 }
1086 
getAccessibleColumnHeaders()1087 Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnHeaders()
1088         throw( RuntimeException )
1089 {
1090     ensureAlive();
1091     return NULL;
1092 }
1093 
getSelectedAccessibleRows()1094 Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleRows()
1095         throw( RuntimeException )
1096 {
1097     ensureAlive();
1098     return Sequence< sal_Int32 >();
1099 }
1100 
getSelectedAccessibleColumns()1101 Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleColumns()
1102         throw( RuntimeException )
1103 {
1104     ScUnoGuard aGuard;
1105     ensureAlive();
1106 
1107     ScCsvGrid& rGrid = implGetGrid();
1108     Sequence< sal_Int32 > aSeq( implGetColumnCount() );
1109 
1110     sal_Int32 nSeqIx = 0;
1111     sal_uInt32 nColIx = rGrid.GetFirstSelected();
1112     for( ; nColIx != CSV_COLUMN_INVALID; ++nSeqIx, nColIx = rGrid.GetNextSelected( nColIx ) )
1113         aSeq[ nSeqIx ] = lcl_GetApiColumn( nColIx );
1114 
1115     aSeq.realloc( nSeqIx );
1116     return aSeq;
1117 }
1118 
isAccessibleRowSelected(sal_Int32)1119 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleRowSelected( sal_Int32 /* nRow */ )
1120         throw( IndexOutOfBoundsException, RuntimeException )
1121 {
1122     ensureAlive();
1123     return sal_False;
1124 }
1125 
isAccessibleColumnSelected(sal_Int32 nColumn)1126 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleColumnSelected( sal_Int32 nColumn )
1127         throw( IndexOutOfBoundsException, RuntimeException )
1128 {
1129     ScUnoGuard aGuard;
1130     ensureAlive();
1131     ensureValidIndex( nColumn );
1132     return implIsColumnSelected( nColumn );
1133 }
1134 
getAccessibleCellAt(sal_Int32 nRow,sal_Int32 nColumn)1135 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
1136         throw( IndexOutOfBoundsException, RuntimeException )
1137 {
1138     ScUnoGuard aGuard;
1139     ensureAlive();
1140     ensureValidPosition( nRow, nColumn );
1141     return implCreateCellObj( nRow, nColumn );
1142 }
1143 
getAccessibleCaption()1144 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCaption()
1145         throw( RuntimeException )
1146 {
1147     ensureAlive();
1148     return NULL;
1149 }
1150 
getAccessibleSummary()1151 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleSummary()
1152         throw( RuntimeException )
1153 {
1154     ensureAlive();
1155     return NULL;
1156 }
1157 
isAccessibleSelected(sal_Int32,sal_Int32 nColumn)1158 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 nColumn )
1159         throw( IndexOutOfBoundsException, RuntimeException )
1160 {
1161     return isAccessibleColumnSelected( nColumn );
1162 }
1163 
getAccessibleIndex(sal_Int32 nRow,sal_Int32 nColumn)1164 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
1165         throw( IndexOutOfBoundsException, RuntimeException )
1166 {
1167     ScUnoGuard aGuard;
1168     ensureAlive();
1169     ensureValidPosition( nRow, nColumn );
1170     return implGetIndex( nRow, nColumn );
1171 }
1172 
getAccessibleRow(sal_Int32 nChildIndex)1173 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRow( sal_Int32 nChildIndex )
1174         throw( IndexOutOfBoundsException, RuntimeException )
1175 {
1176     ScUnoGuard aGuard;
1177     ensureAlive();
1178     ensureValidIndex( nChildIndex );
1179     return implGetRow( nChildIndex );
1180 }
1181 
getAccessibleColumn(sal_Int32 nChildIndex)1182 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumn( sal_Int32 nChildIndex )
1183         throw( IndexOutOfBoundsException, RuntimeException )
1184 {
1185     ScUnoGuard aGuard;
1186     ensureAlive();
1187     ensureValidIndex( nChildIndex );
1188     return implGetColumn( nChildIndex );
1189 }
1190 
1191 
1192 // XAccessibleSelection -------------------------------------------------------
1193 
selectAccessibleChild(sal_Int32 nChildIndex)1194 void SAL_CALL ScAccessibleCsvGrid::selectAccessibleChild( sal_Int32 nChildIndex )
1195         throw( IndexOutOfBoundsException, RuntimeException )
1196 {
1197     ScUnoGuard aGuard;
1198     ensureAlive();
1199     ensureValidIndex( nChildIndex );
1200     sal_Int32 nColumn = implGetColumn( nChildIndex );
1201     if( nChildIndex == 0 )
1202         implGetGrid().SelectAll();
1203     else
1204         implSelectColumn( nColumn, true );
1205 }
1206 
isAccessibleChildSelected(sal_Int32 nChildIndex)1207 sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleChildSelected( sal_Int32 nChildIndex )
1208         throw( IndexOutOfBoundsException, RuntimeException )
1209 {
1210     ScUnoGuard aGuard;
1211     ensureAlive();
1212     ensureValidIndex( nChildIndex );
1213     sal_Int32 nColumn = implGetColumn( nChildIndex );
1214     return implIsColumnSelected( nColumn );
1215 }
1216 
clearAccessibleSelection()1217 void SAL_CALL ScAccessibleCsvGrid::clearAccessibleSelection() throw( RuntimeException )
1218 {
1219     ScUnoGuard aGuard;
1220     ensureAlive();
1221     implGetGrid().SelectAll( false );
1222 }
1223 
selectAllAccessibleChildren()1224 void SAL_CALL ScAccessibleCsvGrid::selectAllAccessibleChildren() throw( RuntimeException )
1225 {
1226     selectAccessibleChild( 0 );
1227 }
1228 
getSelectedAccessibleChildCount()1229 sal_Int32 SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChildCount() throw( RuntimeException )
1230 {
1231     ScUnoGuard aGuard;
1232     ensureAlive();
1233     return implGetRowCount() * implGetSelColumnCount();
1234 }
1235 
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)1236 Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
1237         throw( IndexOutOfBoundsException, RuntimeException )
1238 {
1239     ScUnoGuard aGuard;
1240     ensureAlive();
1241     sal_Int32 nColumns = implGetSelColumnCount();
1242     if( nColumns == 0 )
1243         throw IndexOutOfBoundsException();
1244 
1245     sal_Int32 nRow = nSelectedChildIndex / nColumns;
1246     sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns );
1247     return getAccessibleCellAt( nRow, nColumn );
1248 }
1249 
deselectAccessibleChild(sal_Int32 nSelectedChildIndex)1250 void SAL_CALL ScAccessibleCsvGrid::deselectAccessibleChild( sal_Int32 nSelectedChildIndex )
1251         throw( IndexOutOfBoundsException, RuntimeException )
1252 {
1253     ScUnoGuard aGuard;
1254     ensureAlive();
1255     sal_Int32 nColumns = implGetSelColumnCount();
1256     if( nColumns == 0 )
1257         throw IndexOutOfBoundsException();
1258 
1259     sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns );
1260     ensureValidPosition( nSelectedChildIndex / nColumns, nColumn );
1261     if( nColumn > 0 )
1262         implSelectColumn( nColumn, false );
1263 }
1264 
1265 
1266 // XInterface -----------------------------------------------------------------
1267 
queryInterface(const::com::sun::star::uno::Type & rType)1268 Any SAL_CALL ScAccessibleCsvGrid::queryInterface( const ::com::sun::star::uno::Type& rType )
1269         throw( RuntimeException )
1270 {
1271     Any aAny( ScAccessibleCsvGridImpl::queryInterface( rType ) );
1272     return aAny.hasValue() ? aAny : ScAccessibleCsvControl::queryInterface( rType );
1273 }
1274 
acquire()1275 void SAL_CALL ScAccessibleCsvGrid::acquire() throw ()
1276 {
1277     ScAccessibleCsvControl::acquire();
1278 }
1279 
release()1280 void SAL_CALL ScAccessibleCsvGrid::release() throw ()
1281 {
1282     ScAccessibleCsvControl::release();
1283 }
1284 
1285 
1286 // XServiceInfo ---------------------------------------------------------------
1287 
getImplementationName()1288 OUString SAL_CALL ScAccessibleCsvGrid::getImplementationName() throw( RuntimeException )
1289 {
1290     return CREATE_OUSTRING( GRID_IMPL_NAME );
1291 }
1292 
1293 
1294 // XTypeProvider --------------------------------------------------------------
1295 
getTypes()1296 Sequence< ::com::sun::star::uno::Type > SAL_CALL ScAccessibleCsvGrid::getTypes() throw( RuntimeException )
1297 {
1298     Sequence< ::com::sun::star::uno::Type > aSeq( 2 );
1299     aSeq[ 0 ] = getCppuType( static_cast< const Reference< XAccessibleTable >* >( NULL ) );
1300     aSeq[ 1 ] = getCppuType( static_cast< const Reference< XAccessibleSelection >* >( NULL ) );
1301     return ::comphelper::concatSequences( ScAccessibleCsvControl::getTypes(), aSeq );
1302 }
1303 
getImplementationId()1304 Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvGrid::getImplementationId() throw( RuntimeException )
1305 {
1306     static Sequence< sal_Int8 > aSeq;
1307     getUuid( aSeq );
1308     return aSeq;
1309 }
1310 
1311 
1312 // events ---------------------------------------------------------------------
1313 
SendFocusEvent(bool bFocused)1314 void ScAccessibleCsvGrid::SendFocusEvent( bool bFocused )
1315 {
1316     ScAccessibleCsvControl::SendFocusEvent( bFocused );
1317 
1318     AccessibleEventObject aEvent;
1319     aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
1320     aEvent.Source = Reference< XAccessible >( this );
1321     (bFocused ? aEvent.NewValue : aEvent.OldValue) <<=
1322         getAccessibleCellAt( 0, lcl_GetApiColumn( implGetGrid().GetFocusColumn() ) );
1323     CommitChange( aEvent );
1324 }
1325 
SendTableUpdateEvent(sal_uInt32 nFirstColumn,sal_uInt32 nLastColumn,bool bAllRows)1326 void ScAccessibleCsvGrid::SendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows )
1327 {
1328     if( nFirstColumn <= nLastColumn )
1329     {
1330         AccessibleTableModelChange aModelChange(
1331             AccessibleTableModelChangeType::UPDATE, 0, bAllRows ? implGetRowCount() - 1 : 0,
1332             lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1333         AccessibleEventObject aEvent;
1334         aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
1335         aEvent.Source = Reference< XAccessible >( this );
1336         aEvent.NewValue <<= aModelChange;
1337         CommitChange( aEvent );
1338     }
1339 }
1340 
SendInsertColumnEvent(sal_uInt32 nFirstColumn,sal_uInt32 nLastColumn)1341 void ScAccessibleCsvGrid::SendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
1342 {
1343     if( nFirstColumn <= nLastColumn )
1344     {
1345         AccessibleTableModelChange aModelChange(
1346             AccessibleTableModelChangeType::INSERT, 0, implGetRowCount() - 1,
1347             lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1348         AccessibleEventObject aEvent;
1349         aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
1350         aEvent.Source = Reference< XAccessible >( this );
1351         aEvent.NewValue <<= aModelChange;
1352         CommitChange( aEvent );
1353     }
1354 }
1355 
SendRemoveColumnEvent(sal_uInt32 nFirstColumn,sal_uInt32 nLastColumn)1356 void ScAccessibleCsvGrid::SendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
1357 {
1358     if( nFirstColumn <= nLastColumn )
1359     {
1360         AccessibleTableModelChange aModelChange(
1361             AccessibleTableModelChangeType::DELETE, 0, implGetRowCount() - 1,
1362             lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
1363         AccessibleEventObject aEvent;
1364         aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
1365         aEvent.Source = Reference< XAccessible >( this );
1366         aEvent.NewValue <<= aModelChange;
1367         CommitChange( aEvent );
1368     }
1369 }
1370 
1371 
1372 // helpers --------------------------------------------------------------------
1373 
createAccessibleName()1374 OUString SAL_CALL ScAccessibleCsvGrid::createAccessibleName() throw( RuntimeException )
1375 {
1376     return String( ScResId( STR_ACC_CSVGRID_NAME ) );
1377 }
1378 
createAccessibleDescription()1379 OUString SAL_CALL ScAccessibleCsvGrid::createAccessibleDescription() throw( RuntimeException )
1380 {
1381     return String( ScResId( STR_ACC_CSVGRID_DESCR ) );
1382 }
1383 
ensureValidIndex(sal_Int32 nIndex) const1384 void ScAccessibleCsvGrid::ensureValidIndex( sal_Int32 nIndex ) const
1385         throw( IndexOutOfBoundsException )
1386 {
1387     if( (nIndex < 0) || (nIndex >= implGetCellCount()) )
1388         throw IndexOutOfBoundsException();
1389 }
1390 
ensureValidPosition(sal_Int32 nRow,sal_Int32 nColumn) const1391 void ScAccessibleCsvGrid::ensureValidPosition( sal_Int32 nRow, sal_Int32 nColumn ) const
1392         throw( IndexOutOfBoundsException )
1393 {
1394     if( (nRow < 0) || (nRow >= implGetRowCount()) || (nColumn < 0) || (nColumn >= implGetColumnCount()) )
1395         throw IndexOutOfBoundsException();
1396 }
1397 
implGetGrid() const1398 ScCsvGrid& ScAccessibleCsvGrid::implGetGrid() const
1399 {
1400     return static_cast< ScCsvGrid& >( implGetControl() );
1401 }
1402 
implIsColumnSelected(sal_Int32 nColumn) const1403 bool ScAccessibleCsvGrid::implIsColumnSelected( sal_Int32 nColumn ) const
1404 {
1405     return (nColumn > 0) && implGetGrid().IsSelected( lcl_GetGridColumn( nColumn ) );
1406 }
1407 
implSelectColumn(sal_Int32 nColumn,bool bSelect)1408 void ScAccessibleCsvGrid::implSelectColumn( sal_Int32 nColumn, bool bSelect )
1409 {
1410     if( nColumn > 0 )
1411         implGetGrid().Select( lcl_GetGridColumn( nColumn ), bSelect );
1412 }
1413 
implGetRowCount() const1414 sal_Int32 ScAccessibleCsvGrid::implGetRowCount() const
1415 {
1416     return static_cast< sal_Int32 >( implGetGrid().GetLastVisLine() - implGetGrid().GetFirstVisLine() + 2 );
1417 }
1418 
implGetColumnCount() const1419 sal_Int32 ScAccessibleCsvGrid::implGetColumnCount() const
1420 {
1421     return static_cast< sal_Int32 >( implGetGrid().GetColumnCount() + 1 );
1422 }
1423 
implGetSelColumnCount() const1424 sal_Int32 ScAccessibleCsvGrid::implGetSelColumnCount() const
1425 {
1426     ScCsvGrid& rGrid = implGetGrid();
1427     sal_Int32 nCount = 0;
1428     for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) )
1429         ++nCount;
1430     return nCount;
1431 }
1432 
implGetSelColumn(sal_Int32 nSelColumn) const1433 sal_Int32 ScAccessibleCsvGrid::implGetSelColumn( sal_Int32 nSelColumn ) const
1434 {
1435     ScCsvGrid& rGrid = implGetGrid();
1436     sal_Int32 nColumn = 0;
1437     for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) )
1438     {
1439         if( nColumn == nSelColumn )
1440             return static_cast< sal_Int32 >( nColIx + 1 );
1441         ++nColumn;
1442     }
1443     return 0;
1444 }
1445 
implGetCellText(sal_Int32 nRow,sal_Int32 nColumn) const1446 String ScAccessibleCsvGrid::implGetCellText( sal_Int32 nRow, sal_Int32 nColumn ) const
1447 {
1448     ScCsvGrid& rGrid = implGetGrid();
1449     sal_Int32 nLine = nRow + rGrid.GetFirstVisLine() - 1;
1450     String aCellStr;
1451     if( (nColumn > 0) && (nRow > 0) )
1452         aCellStr = rGrid.GetCellText( lcl_GetGridColumn( nColumn ), nLine );
1453     else if( nRow > 0 )
1454         aCellStr = String::CreateFromInt32( nLine + 1L );
1455     else if( nColumn > 0 )
1456         aCellStr = rGrid.GetColumnTypeName( lcl_GetGridColumn( nColumn ) );
1457     return aCellStr;
1458 }
1459 
1460 
implCreateCellObj(sal_Int32 nRow,sal_Int32 nColumn) const1461 ScAccessibleCsvControl* ScAccessibleCsvGrid::implCreateCellObj( sal_Int32 nRow, sal_Int32 nColumn ) const
1462 {
1463     return new ScAccessibleCsvCell( implGetGrid(), implGetCellText( nRow, nColumn ), nRow, nColumn );
1464 }
1465 
1466 
1467 // ============================================================================
1468 
DBG_NAME(ScAccessibleCsvCell)1469 DBG_NAME( ScAccessibleCsvCell )
1470 
1471 ScAccessibleCsvCell::ScAccessibleCsvCell(
1472         ScCsvGrid& rGrid,
1473         const String& rCellText,
1474         sal_Int32 nRow, sal_Int32 nColumn ) :
1475     ScAccessibleCsvControl( rGrid.GetAccessible(), rGrid, nCellRole ),
1476     AccessibleStaticTextBase( SvxEditSourcePtr( NULL ) ),
1477     maCellText( rCellText ),
1478     mnLine( nRow ? (nRow + rGrid.GetFirstVisLine() - 1) : CSV_LINE_HEADER ),
1479     mnColumn( lcl_GetGridColumn( nColumn ) ),
1480     mnIndex( nRow * (rGrid.GetColumnCount() + 1) + nColumn )
1481 {
1482     DBG_CTOR( ScAccessibleCsvCell, NULL );
1483     SetEditSource( implCreateEditSource() );
1484 }
1485 
~ScAccessibleCsvCell()1486 ScAccessibleCsvCell::~ScAccessibleCsvCell()
1487 {
1488     DBG_DTOR( ScAccessibleCsvCell, NULL );
1489 }
1490 
disposing()1491 void SAL_CALL ScAccessibleCsvCell::disposing()
1492 {
1493     ScUnoGuard aGuard;
1494     SetEditSource( SvxEditSourcePtr( NULL ) );
1495     ScAccessibleCsvControl::disposing();
1496 }
1497 
1498 
1499 // XAccessibleComponent -------------------------------------------------------
1500 
grabFocus()1501 void SAL_CALL ScAccessibleCsvCell::grabFocus() throw( RuntimeException )
1502 {
1503     ScUnoGuard aGuard;
1504     ensureAlive();
1505     ScCsvGrid& rGrid = implGetGrid();
1506     rGrid.Execute( CSVCMD_MOVEGRIDCURSOR, rGrid.GetColumnPos( mnColumn ) );
1507 }
1508 
getForeground()1509 sal_Int32 SAL_CALL ScAccessibleCsvCell::getForeground(  )
1510 throw (RuntimeException)
1511 {
1512     ScUnoGuard aGuard;
1513     ensureAlive();
1514     return implGetGrid().GetSettings().GetStyleSettings().GetButtonTextColor().GetColor();
1515 }
1516 
getBackground()1517 sal_Int32 SAL_CALL ScAccessibleCsvCell::getBackground(  )
1518 throw (RuntimeException)
1519 {
1520     ScUnoGuard aGuard;
1521     ensureAlive();
1522     return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
1523 }
1524 
1525 // XAccessibleContext -----------------------------------------------------
1526 
getAccessibleChildCount()1527 sal_Int32 SAL_CALL ScAccessibleCsvCell::getAccessibleChildCount() throw( RuntimeException )
1528 {
1529     return AccessibleStaticTextBase::getAccessibleChildCount();
1530 }
1531 
getAccessibleChild(sal_Int32 nIndex)1532 Reference< XAccessible > SAL_CALL ScAccessibleCsvCell::getAccessibleChild( sal_Int32 nIndex )
1533         throw( IndexOutOfBoundsException, RuntimeException )
1534 {
1535     return AccessibleStaticTextBase::getAccessibleChild( nIndex );
1536 }
1537 
getAccessibleIndexInParent()1538 sal_Int32 SAL_CALL ScAccessibleCsvCell::getAccessibleIndexInParent() throw( RuntimeException )
1539 {
1540     ScUnoGuard aGuard;
1541     ensureAlive();
1542     return mnIndex;
1543 }
1544 
getAccessibleRelationSet()1545 Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvCell::getAccessibleRelationSet()
1546         throw( RuntimeException )
1547 {
1548     ScUnoGuard aGuard;
1549     ensureAlive();
1550     return new AccessibleRelationSetHelper();
1551 }
1552 
getAccessibleStateSet()1553 Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvCell::getAccessibleStateSet()
1554         throw( RuntimeException )
1555 {
1556     ScUnoGuard aGuard;
1557     AccessibleStateSetHelper* pStateSet = implCreateStateSet();
1558     if( implIsAlive() )
1559     {
1560         const ScCsvGrid& rGrid = implGetGrid();
1561         pStateSet->AddState( AccessibleStateType::SINGLE_LINE );
1562         if( mnColumn != CSV_COLUMN_HEADER )
1563             pStateSet->AddState( AccessibleStateType::SELECTABLE );
1564         if( rGrid.HasFocus() && (rGrid.GetFocusColumn() == mnColumn) && (mnLine == CSV_LINE_HEADER) )
1565             pStateSet->AddState( AccessibleStateType::ACTIVE );
1566         if( rGrid.IsSelected( mnColumn ) )
1567             pStateSet->AddState( AccessibleStateType::SELECTED );
1568     }
1569     return pStateSet;
1570 }
1571 
1572 // XInterface -----------------------------------------------------------------
1573 
IMPLEMENT_FORWARD_XINTERFACE2(ScAccessibleCsvCell,ScAccessibleCsvControl,AccessibleStaticTextBase)1574 IMPLEMENT_FORWARD_XINTERFACE2( ScAccessibleCsvCell, ScAccessibleCsvControl, AccessibleStaticTextBase )
1575 
1576 // XTypeProvider --------------------------------------------------------------
1577 
1578 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScAccessibleCsvCell, ScAccessibleCsvControl, AccessibleStaticTextBase )
1579 
1580 // XServiceInfo ---------------------------------------------------------------
1581 
1582 OUString SAL_CALL ScAccessibleCsvCell::getImplementationName() throw( RuntimeException )
1583 {
1584     return CREATE_OUSTRING( CELL_IMPL_NAME );
1585 }
1586 
1587 // helpers --------------------------------------------------------------------
1588 
GetBoundingBoxOnScreen() const1589 Rectangle ScAccessibleCsvCell::GetBoundingBoxOnScreen() const throw( RuntimeException )
1590 {
1591     ScUnoGuard aGuard;
1592     ensureAlive();
1593     Rectangle aRect( implGetBoundingBox() );
1594     aRect.SetPos( implGetAbsPos( aRect.TopLeft() ) );
1595     return aRect;
1596 }
1597 
GetBoundingBox() const1598 Rectangle ScAccessibleCsvCell::GetBoundingBox() const throw( RuntimeException )
1599 {
1600     ScUnoGuard aGuard;
1601     ensureAlive();
1602     return implGetBoundingBox();
1603 }
1604 
createAccessibleName()1605 OUString SAL_CALL ScAccessibleCsvCell::createAccessibleName() throw( RuntimeException )
1606 {
1607     return maCellText;
1608 }
1609 
createAccessibleDescription()1610 OUString SAL_CALL ScAccessibleCsvCell::createAccessibleDescription() throw( RuntimeException )
1611 {
1612     return OUString();
1613 }
1614 
implGetGrid() const1615 ScCsvGrid& ScAccessibleCsvCell::implGetGrid() const
1616 {
1617     return static_cast< ScCsvGrid& >( implGetControl() );
1618 }
1619 
implGetRealPos() const1620 Point ScAccessibleCsvCell::implGetRealPos() const
1621 {
1622     ScCsvGrid& rGrid = implGetGrid();
1623     return Point(
1624         (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrX() : rGrid.GetColumnX( mnColumn ),
1625         (mnLine == CSV_LINE_HEADER) ? 0 : rGrid.GetY( mnLine ) );
1626 }
1627 
implCalcPixelWidth(sal_uInt32 nChars) const1628 sal_uInt32 ScAccessibleCsvCell::implCalcPixelWidth(sal_uInt32 nChars) const
1629 {
1630     ScCsvGrid& rGrid = implGetGrid();
1631     return rGrid.GetCharWidth() * nChars;
1632 }
1633 
implGetRealSize() const1634 Size ScAccessibleCsvCell::implGetRealSize() const
1635 {
1636     ScCsvGrid& rGrid = implGetGrid();
1637     return Size(
1638         (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrWidth() : implCalcPixelWidth( rGrid.GetColumnWidth( mnColumn ) ),
1639         (mnLine == CSV_LINE_HEADER) ? rGrid.GetHdrHeight() : rGrid.GetLineHeight() );
1640 }
1641 
implGetBoundingBox() const1642 Rectangle ScAccessibleCsvCell::implGetBoundingBox() const
1643 {
1644     ScCsvGrid& rGrid = implGetGrid();
1645     Rectangle aClipRect( Point( 0, 0 ), rGrid.GetSizePixel() );
1646     if( mnColumn != CSV_COLUMN_HEADER )
1647     {
1648         aClipRect.Left() = rGrid.GetFirstX();
1649         aClipRect.Right() = rGrid.GetLastX();
1650     }
1651     if( mnLine != CSV_LINE_HEADER )
1652          aClipRect.Top() = rGrid.GetHdrHeight();
1653 
1654     Rectangle aRect( implGetRealPos(), implGetRealSize() );
1655     aRect.Intersection( aClipRect );
1656     if( (aRect.GetWidth() <= 0) || (aRect.GetHeight() <= 0) )
1657         aRect.SetSize( Size( -1, -1 ) );
1658     return aRect;
1659 }
1660 
implCreateEditSource()1661 ::std::auto_ptr< SvxEditSource > ScAccessibleCsvCell::implCreateEditSource()
1662 {
1663     ScCsvGrid& rGrid = implGetGrid();
1664     Rectangle aBoundRect( implGetBoundingBox() );
1665     aBoundRect -= implGetRealPos();
1666 
1667     ::std::auto_ptr< ScAccessibleTextData > pCsvTextData( new ScAccessibleCsvTextData(
1668         &rGrid, rGrid.GetEditEngine(), maCellText, aBoundRect, implGetRealSize() ) );
1669 
1670     ::std::auto_ptr< SvxEditSource > pEditSource( new ScAccessibilityEditSource( pCsvTextData ) );
1671     return pEditSource;
1672 }
1673 
1674 
1675 // ============================================================================
1676 
1677