1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <extended/AccessibleGridControlTableCell.hxx>
21 #include <toolkit/helper/convert.hxx>
22 #include <vcl/accessibletable.hxx>
23 #include <vcl/svapp.hxx>
24 #include <tools/gen.hxx>
25 #include <tools/debug.hxx>
26 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
27 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
28 
29 namespace accessibility
30 {
31     namespace
32     {
33         // FIXME this is a copy'n'paste from
34         // source/extended/AccessibleBrowseBoxTableCell.cxx, get rid of that...
35         /// @throws css::lang::IndexOutOfBoundsException
checkIndex_Impl(sal_Int32 _nIndex,const OUString & _sText)36         void checkIndex_Impl( sal_Int32 _nIndex, const OUString& _sText )
37         {
38             if ( _nIndex >= _sText.getLength() )
39                 throw css::lang::IndexOutOfBoundsException();
40         }
41     }
42     using namespace ::com::sun::star::lang;
43     using namespace utl;
44     using namespace comphelper;
45     using namespace ::com::sun::star::uno;
46     using ::com::sun::star::accessibility::XAccessible;
47     using namespace ::com::sun::star::accessibility;
48     using namespace ::vcl;
49     using namespace ::vcl::table;
50 
51 
52     // = AccessibleGridControlCell
53 
54 
AccessibleGridControlCell(const css::uno::Reference<css::accessibility::XAccessible> & _rxParent,::vcl::table::IAccessibleTable & _rTable,sal_Int32 _nRowPos,sal_uInt16 _nColPos,::vcl::table::AccessibleTableControlObjType _eType)55     AccessibleGridControlCell::AccessibleGridControlCell(
56             const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, ::vcl::table::IAccessibleTable& _rTable,
57             sal_Int32 _nRowPos, sal_uInt16 _nColPos, ::vcl::table::AccessibleTableControlObjType _eType )
58         :AccessibleGridControlBase( _rxParent, _rTable, _eType )
59         ,m_nRowPos( _nRowPos )
60         ,m_nColPos( _nColPos )
61     {
62         // set accessible name here, because for that we need the position of the cell
63         // and so the base class isn't capable of doing this
64         OUString aAccName;
65         if(_eType == TCTYPE_TABLECELL)
66             aAccName = _rTable.GetAccessibleObjectName( TCTYPE_TABLECELL, _nRowPos, _nColPos );
67         else if(_eType == TCTYPE_ROWHEADERCELL)
68             aAccName = _rTable.GetAccessibleObjectName( TCTYPE_ROWHEADERCELL, _nRowPos, 0 );
69         else if(_eType == TCTYPE_COLUMNHEADERCELL)
70             aAccName = _rTable.GetAccessibleObjectName( TCTYPE_COLUMNHEADERCELL, 0, _nRowPos );
71         implSetName( aAccName );
72     }
73 
grabFocus()74     void SAL_CALL AccessibleGridControlCell::grabFocus()
75     {
76         SolarMutexGuard aSolarGuard;
77 
78         m_aTable.GoToCell( m_nColPos, m_nRowPos );
79     }
80 
81     // implementation of a table cell
implGetText()82     OUString AccessibleGridControlTableCell::implGetText()
83     {
84         ensureIsAlive();
85         return m_aTable.GetAccessibleCellText( getRowPos(),  getColumnPos() );
86     }
87 
implGetLocale()88     css::lang::Locale AccessibleGridControlTableCell::implGetLocale()
89     {
90         ensureIsAlive();
91         return m_aTable.GetAccessible()->getAccessibleContext()->getLocale();
92     }
93 
implGetSelection(sal_Int32 & nStartIndex,sal_Int32 & nEndIndex)94     void AccessibleGridControlTableCell::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
95     {
96         nStartIndex = 0;
97         nEndIndex = 0;
98     }
99 
AccessibleGridControlTableCell(const css::uno::Reference<XAccessible> & _rxParent,::vcl::table::IAccessibleTable & _rTable,sal_Int32 _nRowPos,sal_uInt16 _nColPos)100     AccessibleGridControlTableCell::AccessibleGridControlTableCell(const css::uno::Reference<XAccessible >& _rxParent,
101                                 ::vcl::table::IAccessibleTable& _rTable,
102                                 sal_Int32 _nRowPos,
103                                 sal_uInt16 _nColPos)
104         :AccessibleGridControlCell( _rxParent, _rTable, _nRowPos, _nColPos, TCTYPE_TABLECELL )
105     {
106     }
107 
108     // XInterface
109 
110     /** Queries for a new interface. */
queryInterface(const css::uno::Type & rType)111     css::uno::Any SAL_CALL AccessibleGridControlTableCell::queryInterface(
112             const css::uno::Type& rType )
113     {
114         Any aRet = AccessibleGridControlCell::queryInterface(rType);
115         if ( !aRet.hasValue() )
116             aRet = AccessibleTextHelper_BASE::queryInterface(rType);
117         return aRet;
118     }
119 
120     /** Acquires the object (calls acquire() on base class). */
acquire()121     void SAL_CALL AccessibleGridControlTableCell::acquire() noexcept
122     {
123         AccessibleGridControlCell::acquire();
124     }
125 
126     /** Releases the object (calls release() on base class). */
release()127     void SAL_CALL AccessibleGridControlTableCell::release() noexcept
128     {
129         AccessibleGridControlCell::release();
130     }
131 
getCharacterBounds(sal_Int32 nIndex)132     css::awt::Rectangle SAL_CALL AccessibleGridControlTableCell::getCharacterBounds( sal_Int32 nIndex )
133     {
134         SolarMutexGuard aSolarGuard;
135 
136         ensureIsAlive();
137         if ( !implIsValidIndex( nIndex, implGetText().getLength() ) )
138             throw IndexOutOfBoundsException();
139 
140         return AWTRectangle( m_aTable.GetFieldCharacterBounds( getRowPos(), getColumnPos(), nIndex ) );
141     }
142 
getIndexAtPoint(const css::awt::Point & _aPoint)143     sal_Int32 SAL_CALL AccessibleGridControlTableCell::getIndexAtPoint( const css::awt::Point& _aPoint )
144     {
145         SolarMutexGuard aSolarGuard;
146 
147         ensureIsAlive();
148 
149         return m_aTable.GetFieldIndexAtPoint( getRowPos(), getColumnPos(), VCLPoint( _aPoint ) );
150     }
151 
152     /** @return
153             The name of this class.
154     */
getImplementationName()155     OUString SAL_CALL AccessibleGridControlTableCell::getImplementationName()
156     {
157         return "com.sun.star.accessibility.AccessibleGridControlTableCell";
158     }
159 
160     /** @return  The count of visible children. */
getAccessibleChildCount()161     sal_Int32 SAL_CALL AccessibleGridControlTableCell::getAccessibleChildCount()
162     {
163         return 0;
164     }
165 
166     /** @return  The css::accessibility::XAccessible interface of the specified child. */
getAccessibleChild(sal_Int32)167     css::uno::Reference< css::accessibility::XAccessible > SAL_CALL AccessibleGridControlTableCell::getAccessibleChild( sal_Int32 )
168     {
169         throw css::lang::IndexOutOfBoundsException();
170     }
171 
172     /** Creates a new AccessibleStateSetHelper and fills it with states of the
173         current object.
174         @return
175             A filled AccessibleStateSetHelper.
176     */
implCreateStateSetHelper()177     rtl::Reference<::utl::AccessibleStateSetHelper> AccessibleGridControlTableCell::implCreateStateSetHelper()
178     {
179         rtl::Reference<::utl::AccessibleStateSetHelper> pStateSetHelper = new ::utl::AccessibleStateSetHelper;
180 
181         if( isAlive() )
182         {
183             // SHOWING done with mxParent
184             if( implIsShowing() )
185                 pStateSetHelper->AddState( AccessibleStateType::SHOWING );
186 
187             m_aTable.FillAccessibleStateSetForCell( *pStateSetHelper, getRowPos(), static_cast< sal_uInt16 >( getColumnPos() ) );
188         }
189         else
190             pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
191 
192         return pStateSetHelper;
193     }
194 
195 
196     // css::accessibility::XAccessible
197 
198     /** @return  The css::accessibility::XAccessibleContext interface of this object. */
getAccessibleContext()199     css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL AccessibleGridControlTableCell::getAccessibleContext()
200     {
201         SolarMutexGuard g;
202 
203         ensureIsAlive();
204         return this;
205     }
206 
207     // css::accessibility::XAccessibleContext
208 
getAccessibleIndexInParent()209     sal_Int32 SAL_CALL AccessibleGridControlTableCell::getAccessibleIndexInParent()
210     {
211         SolarMutexGuard aSolarGuard;
212 
213         ensureIsAlive();
214 
215         return ( getRowPos() * m_aTable.GetColumnCount() ) + getColumnPos();
216     }
217 
getCaretPosition()218     sal_Int32 SAL_CALL AccessibleGridControlTableCell::getCaretPosition(  )
219     {
220         return -1;
221     }
setCaretPosition(sal_Int32 nIndex)222     sal_Bool SAL_CALL AccessibleGridControlTableCell::setCaretPosition ( sal_Int32 nIndex )
223     {
224         SolarMutexGuard aSolarGuard;
225 
226         if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) )
227             throw IndexOutOfBoundsException();
228 
229         return false;
230     }
getCharacter(sal_Int32 nIndex)231     sal_Unicode SAL_CALL AccessibleGridControlTableCell::getCharacter( sal_Int32 nIndex )
232     {
233         SolarMutexGuard aSolarGuard;
234 
235         return OCommonAccessibleText::implGetCharacter( implGetText(), nIndex );
236     }
getCharacterAttributes(sal_Int32 nIndex,const css::uno::Sequence<OUString> &)237     css::uno::Sequence< css::beans::PropertyValue > SAL_CALL AccessibleGridControlTableCell::getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& )
238     {
239         SolarMutexGuard aSolarGuard;
240 
241         OUString sText( implGetText() );
242 
243         if ( !implIsValidIndex( nIndex, sText.getLength() ) )
244             throw IndexOutOfBoundsException();
245 
246         return css::uno::Sequence< css::beans::PropertyValue >();
247     }
getCharacterCount()248     sal_Int32 SAL_CALL AccessibleGridControlTableCell::getCharacterCount(  )
249     {
250         SolarMutexGuard aSolarGuard;
251 
252         return implGetText().getLength();
253     }
254 
getSelectedText()255     OUString SAL_CALL AccessibleGridControlTableCell::getSelectedText(  )
256     {
257         SolarMutexGuard aSolarGuard;
258 
259         return OUString();
260     }
getSelectionStart()261     sal_Int32 SAL_CALL AccessibleGridControlTableCell::getSelectionStart(  )
262     {
263         SolarMutexGuard aSolarGuard;
264 
265         return 0;
266     }
getSelectionEnd()267     sal_Int32 SAL_CALL AccessibleGridControlTableCell::getSelectionEnd(  )
268     {
269         SolarMutexGuard aSolarGuard;
270 
271         return 0;
272     }
setSelection(sal_Int32 nStartIndex,sal_Int32 nEndIndex)273     sal_Bool SAL_CALL AccessibleGridControlTableCell::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
274     {
275         SolarMutexGuard aSolarGuard;
276 
277         if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) )
278             throw IndexOutOfBoundsException();
279 
280         return false;
281     }
getText()282     OUString SAL_CALL AccessibleGridControlTableCell::getText(  )
283     {
284         SolarMutexGuard aSolarGuard;
285 
286         return implGetText(  );
287     }
getTextRange(sal_Int32 nStartIndex,sal_Int32 nEndIndex)288     OUString SAL_CALL AccessibleGridControlTableCell::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
289     {
290         SolarMutexGuard aSolarGuard;
291 
292         return OCommonAccessibleText::implGetTextRange( implGetText(), nStartIndex, nEndIndex );
293     }
getTextAtIndex(sal_Int32 nIndex,sal_Int16 aTextType)294     css::accessibility::TextSegment SAL_CALL AccessibleGridControlTableCell::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType )
295     {
296         SolarMutexGuard aSolarGuard;
297 
298         return OCommonAccessibleText::getTextAtIndex( nIndex ,aTextType);
299     }
getTextBeforeIndex(sal_Int32 nIndex,sal_Int16 aTextType)300     css::accessibility::TextSegment SAL_CALL AccessibleGridControlTableCell::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType )
301     {
302         SolarMutexGuard aSolarGuard;
303 
304         return OCommonAccessibleText::getTextBeforeIndex( nIndex ,aTextType);
305     }
getTextBehindIndex(sal_Int32 nIndex,sal_Int16 aTextType)306     css::accessibility::TextSegment SAL_CALL AccessibleGridControlTableCell::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType )
307     {
308         SolarMutexGuard aSolarGuard;
309 
310         return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType);
311     }
copyText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)312     sal_Bool SAL_CALL AccessibleGridControlTableCell::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
313     {
314         SolarMutexGuard aSolarGuard;
315 
316         OUString sText = implGetText();
317         checkIndex_Impl( nStartIndex, sText );
318         checkIndex_Impl( nEndIndex, sText );
319 
320         //!!! don't know how to put a string into the clipboard
321         return false;
322     }
scrollSubstringTo(sal_Int32,sal_Int32,AccessibleScrollType)323     sal_Bool SAL_CALL AccessibleGridControlTableCell::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType )
324     {
325         return false;
326     }
327 
implGetBoundingBox()328     tools::Rectangle AccessibleGridControlTableCell::implGetBoundingBox()
329     {
330         vcl::Window* pParent = m_aTable.GetAccessibleParentWindow();
331         DBG_ASSERT( pParent, "implGetBoundingBox - missing parent window" );
332         tools::Rectangle aGridRect = m_aTable.GetWindowExtentsRelative( pParent );
333         sal_Int32 nIndex = getAccessibleIndexInParent();
334         tools::Rectangle aCellRect = m_aTable.calcCellRect(nIndex%m_aTable.GetColumnCount(), nIndex/m_aTable.GetColumnCount());
335         tools::Long nX = aGridRect.Left() + aCellRect.Left();
336         tools::Long nY = aGridRect.Top() + aCellRect.Top();
337         tools::Rectangle aCell( Point( nX, nY ), aCellRect.GetSize());
338         return aCell;
339     }
340 
implGetBoundingBoxOnScreen()341     tools::Rectangle AccessibleGridControlTableCell::implGetBoundingBoxOnScreen()
342     {
343         tools::Rectangle aGridRect = m_aTable.GetWindowExtentsRelative( nullptr );
344         sal_Int32 nIndex = getAccessibleIndexInParent();
345         tools::Rectangle aCellRect = m_aTable.calcCellRect(nIndex%m_aTable.GetColumnCount(), nIndex/m_aTable.GetColumnCount());
346         tools::Long nX = aGridRect.Left() + aCellRect.Left();
347         tools::Long nY = aGridRect.Top() + aCellRect.Top();
348         tools::Rectangle aCell( Point( nX, nY ), aCellRect.GetSize());
349         return aCell;
350     }
351 }
352 
353 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
354