xref: /AOO41X/main/sc/source/ui/Accessibility/AccessiblePreviewHeaderCell.cxx (revision b3f79822e811ac3493b185030a72c3c5a51f32d8)
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 #include "scitems.hxx"
27 #include <editeng/eeitem.hxx>
28 #include <tools/gen.hxx>
29 #include "AccessibleText.hxx"
30 #include "editsrc.hxx"
31 #include <svx/AccessibleTextHelper.hxx>
32 #include "AccessiblePreviewHeaderCell.hxx"
33 #include "AccessibilityHints.hxx"
34 #include "prevwsh.hxx"
35 #include "unoguard.hxx"
36 #include "miscuno.hxx"
37 #include "prevloc.hxx"
38 #include "scresid.hxx"
39 #ifndef SC_SC_HRC
40 #include "sc.hrc"
41 #endif
42 
43 #include <com/sun/star/accessibility/AccessibleRole.hpp>
44 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
45 
46 #include <vcl/window.hxx>
47 #include <svl/smplhint.hxx>
48 #include <unotools/accessiblestatesethelper.hxx>
49 #include <comphelper/sequence.hxx>
50 #include <toolkit/helper/convert.hxx>
51 
52 using namespace ::com::sun::star;
53 using namespace ::com::sun::star::accessibility;
54 
55 //=====  internal  ============================================================
56 
ScAccessiblePreviewHeaderCell(const::com::sun::star::uno::Reference<::com::sun::star::accessibility::XAccessible> & rxParent,ScPreviewShell * pViewShell,const ScAddress & rCellPos,sal_Bool bIsColHdr,sal_Bool bIsRowHdr,sal_Int32 nIndex)57 ScAccessiblePreviewHeaderCell::ScAccessiblePreviewHeaderCell( const ::com::sun::star::uno::Reference<
58                                 ::com::sun::star::accessibility::XAccessible>& rxParent,
59                             ScPreviewShell* pViewShell,
60                             const ScAddress& rCellPos, sal_Bool bIsColHdr, sal_Bool bIsRowHdr,
61                             sal_Int32 nIndex ) :
62     ScAccessibleContextBase( rxParent, AccessibleRole::TABLE_CELL ),
63     mpViewShell( pViewShell ),
64     mpTextHelper( NULL ),
65     mnIndex( nIndex ),
66     maCellPos( rCellPos ),
67     mbColumnHeader( bIsColHdr ),
68     mbRowHeader( bIsRowHdr ),
69     mpTableInfo( NULL )
70 {
71     if (mpViewShell)
72         mpViewShell->AddAccessibilityObject(*this);
73 }
74 
~ScAccessiblePreviewHeaderCell()75 ScAccessiblePreviewHeaderCell::~ScAccessiblePreviewHeaderCell()
76 {
77     if (mpViewShell)
78         mpViewShell->RemoveAccessibilityObject(*this);
79 }
80 
disposing()81 void SAL_CALL ScAccessiblePreviewHeaderCell::disposing()
82 {
83     ScUnoGuard aGuard;
84     if (mpViewShell)
85     {
86         mpViewShell->RemoveAccessibilityObject(*this);
87         mpViewShell = NULL;
88     }
89 
90     if (mpTableInfo)
91         DELETEZ (mpTableInfo);
92 
93     ScAccessibleContextBase::disposing();
94 }
95 
96 //=====  SfxListener  =====================================================
97 
Notify(SfxBroadcaster & rBC,const SfxHint & rHint)98 void ScAccessiblePreviewHeaderCell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
99 {
100     if (rHint.ISA( SfxSimpleHint ))
101     {
102         const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
103         sal_uLong nId = rRef.GetId();
104         if (nId == SC_HINT_ACC_VISAREACHANGED)
105         {
106             if (mpTextHelper)
107                 mpTextHelper->UpdateChildren();
108         }
109         else if ( nId == SFX_HINT_DATACHANGED )
110         {
111             //  column / row layout may change with any document change,
112             //  so it must be invalidated
113             DELETEZ( mpTableInfo );
114         }
115     }
116 
117     ScAccessibleContextBase::Notify(rBC, rHint);
118 }
119 
120 //=====  XInterface  =====================================================
121 
queryInterface(uno::Type const & rType)122 uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::queryInterface( uno::Type const & rType )
123     throw (uno::RuntimeException)
124 {
125     uno::Any aAny (ScAccessiblePreviewHeaderCellImpl::queryInterface(rType));
126     return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
127 }
128 
acquire()129 void SAL_CALL ScAccessiblePreviewHeaderCell::acquire()
130     throw ()
131 {
132     ScAccessibleContextBase::acquire();
133 }
134 
release()135 void SAL_CALL ScAccessiblePreviewHeaderCell::release()
136     throw ()
137 {
138     ScAccessibleContextBase::release();
139 }
140 
141 //=====  XAccessibleValue  ================================================
142 
getCurrentValue()143 uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getCurrentValue() throw (uno::RuntimeException)
144 {
145     ScUnoGuard aGuard;
146     IsObjectValid();
147 
148     double fValue(0.0);
149     if (mbColumnHeader)
150         fValue = maCellPos.Col();
151     else
152         fValue = maCellPos.Row();
153 
154     uno::Any aAny;
155     aAny <<= fValue;
156     return aAny;
157 }
158 
setCurrentValue(const uno::Any &)159 sal_Bool SAL_CALL ScAccessiblePreviewHeaderCell::setCurrentValue( const uno::Any& /* aNumber */ )
160                                                                 throw (uno::RuntimeException)
161 {
162     //  it is not possible to set a value
163     return sal_False;
164 }
165 
getMaximumValue()166 uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getMaximumValue() throw (uno::RuntimeException)
167 {
168     ScUnoGuard aGuard;
169     IsObjectValid();
170 
171     double fValue(0.0);
172     if (mbColumnHeader)
173         fValue = MAXCOL;
174     else
175         fValue = MAXROW;
176     uno::Any aAny;
177     aAny <<= fValue;
178     return aAny;
179 }
180 
getMinimumValue()181 uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getMinimumValue() throw (uno::RuntimeException)
182 {
183     double fValue(0.0);
184     uno::Any aAny;
185     aAny <<= fValue;
186     return aAny;
187 }
188 
189 //=====  XAccessibleComponent  ============================================
190 
getAccessibleAtPoint(const awt::Point & rPoint)191 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleAtPoint( const awt::Point& rPoint )
192                                 throw (uno::RuntimeException)
193 {
194     uno::Reference<XAccessible> xRet;
195     if (containsPoint(rPoint))
196     {
197         ScUnoGuard aGuard;
198         IsObjectValid();
199 
200         if(!mpTextHelper)
201             CreateTextHelper();
202 
203         xRet = mpTextHelper->GetAt(rPoint);
204     }
205 
206     return xRet;
207 }
208 
grabFocus()209 void SAL_CALL ScAccessiblePreviewHeaderCell::grabFocus() throw (uno::RuntimeException)
210 {
211     ScUnoGuard aGuard;
212     IsObjectValid();
213     if (getAccessibleParent().is())
214     {
215         uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
216         if (xAccessibleComponent.is())
217             xAccessibleComponent->grabFocus();
218     }
219 }
220 
221 //=====  XAccessibleContext  ==============================================
222 
getAccessibleChildCount()223 sal_Int32 SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleChildCount() throw(uno::RuntimeException)
224 {
225     ScUnoGuard aGuard;
226     IsObjectValid();
227     if (!mpTextHelper)
228         CreateTextHelper();
229     return mpTextHelper->GetChildCount();
230 }
231 
getAccessibleChild(sal_Int32 nIndex)232 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleChild(sal_Int32 nIndex)
233                             throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
234 {
235     ScUnoGuard aGuard;
236     IsObjectValid();
237     if (!mpTextHelper)
238         CreateTextHelper();
239     return mpTextHelper->GetChild(nIndex);
240 }
241 
getAccessibleIndexInParent()242 sal_Int32 SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleIndexInParent() throw (uno::RuntimeException)
243 {
244     return mnIndex;
245 }
246 
getAccessibleStateSet()247 uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleStateSet()
248                             throw(uno::RuntimeException)
249 {
250     ScUnoGuard aGuard;
251 
252     uno::Reference<XAccessibleStateSet> xParentStates;
253     if (getAccessibleParent().is())
254     {
255         uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
256         xParentStates = xParentContext->getAccessibleStateSet();
257     }
258     utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
259     if (IsDefunc(xParentStates))
260         pStateSet->AddState(AccessibleStateType::DEFUNC);
261     else
262     {
263         pStateSet->AddState(AccessibleStateType::ENABLED);
264         pStateSet->AddState(AccessibleStateType::MULTI_LINE);
265         if (isShowing())
266             pStateSet->AddState(AccessibleStateType::SHOWING);
267         pStateSet->AddState(AccessibleStateType::TRANSIENT);
268         if (isVisible())
269             pStateSet->AddState(AccessibleStateType::VISIBLE);
270     }
271     return pStateSet;
272 }
273 
274 //=====  XServiceInfo  ====================================================
275 
getImplementationName()276 rtl::OUString SAL_CALL ScAccessiblePreviewHeaderCell::getImplementationName() throw(uno::RuntimeException)
277 {
278     return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessiblePreviewHeaderCell"));
279 }
280 
getSupportedServiceNames()281 uno::Sequence<rtl::OUString> SAL_CALL ScAccessiblePreviewHeaderCell::getSupportedServiceNames()
282                                                     throw(uno::RuntimeException)
283 {
284     uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
285     sal_Int32 nOldSize(aSequence.getLength());
286     aSequence.realloc(nOldSize + 1);
287     ::rtl::OUString* pNames = aSequence.getArray();
288 
289     pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.AccessibleCellView"));
290 
291     return aSequence;
292 }
293 
294 //=====  XTypeProvider  =======================================================
295 
getTypes()296 uno::Sequence< uno::Type > SAL_CALL ScAccessiblePreviewHeaderCell::getTypes()
297         throw (uno::RuntimeException)
298 {
299     return comphelper::concatSequences(ScAccessiblePreviewHeaderCellImpl::getTypes(), ScAccessibleContextBase::getTypes());
300 }
301 
302 uno::Sequence<sal_Int8> SAL_CALL
getImplementationId(void)303     ScAccessiblePreviewHeaderCell::getImplementationId(void)
304     throw (uno::RuntimeException)
305 {
306     ScUnoGuard aGuard;
307     IsObjectValid();
308     static uno::Sequence<sal_Int8> aId;
309     if (aId.getLength() == 0)
310     {
311         aId.realloc (16);
312         rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
313     }
314     return aId;
315 }
316 
317 //====  internal  =========================================================
318 
GetBoundingBoxOnScreen() const319 Rectangle ScAccessiblePreviewHeaderCell::GetBoundingBoxOnScreen() const throw (uno::RuntimeException)
320 {
321     Rectangle aCellRect;
322 
323     FillTableInfo();
324 
325     if (mpTableInfo)
326     {
327         const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[maCellPos.Col()];
328         const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[maCellPos.Row()];
329 
330         aCellRect = Rectangle( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
331     }
332 
333     if (mpViewShell)
334     {
335         Window* pWindow = mpViewShell->GetWindow();
336         if (pWindow)
337         {
338             Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
339             aCellRect.setX(aCellRect.getX() + aRect.getX());
340             aCellRect.setY(aCellRect.getY() + aRect.getY());
341         }
342     }
343     return aCellRect;
344 }
345 
GetBoundingBox() const346 Rectangle ScAccessiblePreviewHeaderCell::GetBoundingBox() const throw (uno::RuntimeException)
347 {
348     FillTableInfo();
349 
350     if (mpTableInfo)
351     {
352         const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[maCellPos.Col()];
353         const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[maCellPos.Row()];
354 
355         Rectangle aCellRect( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
356         uno::Reference<XAccessible> xAccParent = const_cast<ScAccessiblePreviewHeaderCell*>(this)->getAccessibleParent();
357         if (xAccParent.is())
358         {
359             uno::Reference<XAccessibleContext> xAccParentContext = xAccParent->getAccessibleContext();
360             uno::Reference<XAccessibleComponent> xAccParentComp (xAccParentContext, uno::UNO_QUERY);
361             if (xAccParentComp.is())
362             {
363                 Rectangle aParentRect (VCLRectangle(xAccParentComp->getBounds()));
364                 aCellRect.setX(aCellRect.getX() - aParentRect.getX());
365                 aCellRect.setY(aCellRect.getY() - aParentRect.getY());
366             }
367         }
368         return aCellRect;
369     }
370     return Rectangle();
371 }
372 
createAccessibleDescription()373 rtl::OUString SAL_CALL ScAccessiblePreviewHeaderCell::createAccessibleDescription() throw(uno::RuntimeException)
374 {
375     rtl::OUString sDescription = String(ScResId(STR_ACC_HEADERCELL_DESCR));
376     return sDescription;
377 }
378 
createAccessibleName()379 rtl::OUString SAL_CALL ScAccessiblePreviewHeaderCell::createAccessibleName() throw(uno::RuntimeException)
380 {
381     rtl::OUString sName = String(ScResId(STR_ACC_HEADERCELL_NAME));
382 
383     if ( mbColumnHeader )
384     {
385         if ( mbRowHeader )
386         {
387             //! name for corner cell?
388 
389 //          sName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Column/Row Header"));
390         }
391         else
392         {
393             // name of column header
394             sName += ScColToAlpha( maCellPos.Col() );
395         }
396     }
397     else
398     {
399         // name of row header
400         sName += rtl::OUString::valueOf( (sal_Int32) ( maCellPos.Row() + 1 ) );
401     }
402 
403     return sName;
404 }
405 
IsDefunc(const uno::Reference<XAccessibleStateSet> & rxParentStates)406 sal_Bool ScAccessiblePreviewHeaderCell::IsDefunc( const uno::Reference<XAccessibleStateSet>& rxParentStates )
407 {
408     return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
409         (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
410 }
411 
CreateTextHelper()412 void ScAccessiblePreviewHeaderCell::CreateTextHelper()
413 {
414     if (!mpTextHelper)
415     {
416         ::std::auto_ptr < ScAccessibleTextData > pAccessiblePreviewHeaderCellTextData
417             (new ScAccessiblePreviewHeaderCellTextData(mpViewShell, String(getAccessibleName()), maCellPos, mbColumnHeader, mbRowHeader));
418         ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessiblePreviewHeaderCellTextData));
419 
420         mpTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource );
421         mpTextHelper->SetEventSource(this);
422     }
423 }
424 
FillTableInfo() const425 void ScAccessiblePreviewHeaderCell::FillTableInfo() const
426 {
427     if ( mpViewShell && !mpTableInfo )
428     {
429         Size aOutputSize;
430         Window* pWindow = mpViewShell->GetWindow();
431         if ( pWindow )
432             aOutputSize = pWindow->GetOutputSizePixel();
433         Point aPoint;
434         Rectangle aVisRect( aPoint, aOutputSize );
435 
436         mpTableInfo = new ScPreviewTableInfo;
437         mpViewShell->GetLocationData().GetTableInfo( aVisRect, *mpTableInfo );
438     }
439 }
440