xref: /trunk/main/sc/source/ui/Accessibility/AccessiblePreviewHeaderCell.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 {
124     uno::Any aAny (ScAccessiblePreviewHeaderCellImpl::queryInterface(rType));
125     return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
126 }
127 
acquire()128 void SAL_CALL ScAccessiblePreviewHeaderCell::acquire()
129     throw ()
130 {
131     ScAccessibleContextBase::acquire();
132 }
133 
release()134 void SAL_CALL ScAccessiblePreviewHeaderCell::release()
135     throw ()
136 {
137     ScAccessibleContextBase::release();
138 }
139 
140 //=====  XAccessibleValue  ================================================
141 
getCurrentValue()142 uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getCurrentValue()
143 {
144     ScUnoGuard aGuard;
145     IsObjectValid();
146 
147     double fValue(0.0);
148     if (mbColumnHeader)
149         fValue = maCellPos.Col();
150     else
151         fValue = maCellPos.Row();
152 
153     uno::Any aAny;
154     aAny <<= fValue;
155     return aAny;
156 }
157 
setCurrentValue(const uno::Any &)158 sal_Bool SAL_CALL ScAccessiblePreviewHeaderCell::setCurrentValue( const uno::Any& /* aNumber */ )
159 {
160     //  it is not possible to set a value
161     return sal_False;
162 }
163 
getMaximumValue()164 uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getMaximumValue()
165 {
166     ScUnoGuard aGuard;
167     IsObjectValid();
168 
169     double fValue(0.0);
170     if (mbColumnHeader)
171         fValue = MAXCOL;
172     else
173         fValue = MAXROW;
174     uno::Any aAny;
175     aAny <<= fValue;
176     return aAny;
177 }
178 
getMinimumValue()179 uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getMinimumValue()
180 {
181     double fValue(0.0);
182     uno::Any aAny;
183     aAny <<= fValue;
184     return aAny;
185 }
186 
187 //=====  XAccessibleComponent  ============================================
188 
getAccessibleAtPoint(const awt::Point & rPoint)189 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleAtPoint( const awt::Point& rPoint )
190 {
191     uno::Reference<XAccessible> xRet;
192     if (containsPoint(rPoint))
193     {
194         ScUnoGuard aGuard;
195         IsObjectValid();
196 
197         if(!mpTextHelper)
198             CreateTextHelper();
199 
200         xRet = mpTextHelper->GetAt(rPoint);
201     }
202 
203     return xRet;
204 }
205 
grabFocus()206 void SAL_CALL ScAccessiblePreviewHeaderCell::grabFocus()
207 {
208     ScUnoGuard aGuard;
209     IsObjectValid();
210     if (getAccessibleParent().is())
211     {
212         uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
213         if (xAccessibleComponent.is())
214             xAccessibleComponent->grabFocus();
215     }
216 }
217 
218 //=====  XAccessibleContext  ==============================================
219 
getAccessibleChildCount()220 sal_Int32 SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleChildCount()
221 {
222     ScUnoGuard aGuard;
223     IsObjectValid();
224     if (!mpTextHelper)
225         CreateTextHelper();
226     return mpTextHelper->GetChildCount();
227 }
228 
getAccessibleChild(sal_Int32 nIndex)229 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleChild(sal_Int32 nIndex)
230 {
231     ScUnoGuard aGuard;
232     IsObjectValid();
233     if (!mpTextHelper)
234         CreateTextHelper();
235     return mpTextHelper->GetChild(nIndex);
236 }
237 
getAccessibleIndexInParent()238 sal_Int32 SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleIndexInParent()
239 {
240     return mnIndex;
241 }
242 
getAccessibleStateSet()243 uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleStateSet()
244 {
245     ScUnoGuard aGuard;
246 
247     uno::Reference<XAccessibleStateSet> xParentStates;
248     if (getAccessibleParent().is())
249     {
250         uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
251         xParentStates = xParentContext->getAccessibleStateSet();
252     }
253     utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
254     if (IsDefunc(xParentStates))
255         pStateSet->AddState(AccessibleStateType::DEFUNC);
256     else
257     {
258         pStateSet->AddState(AccessibleStateType::ENABLED);
259         pStateSet->AddState(AccessibleStateType::MULTI_LINE);
260         if (isShowing())
261             pStateSet->AddState(AccessibleStateType::SHOWING);
262         pStateSet->AddState(AccessibleStateType::TRANSIENT);
263         if (isVisible())
264             pStateSet->AddState(AccessibleStateType::VISIBLE);
265     }
266     return pStateSet;
267 }
268 
269 //=====  XServiceInfo  ====================================================
270 
getImplementationName()271 rtl::OUString SAL_CALL ScAccessiblePreviewHeaderCell::getImplementationName()
272 {
273     return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessiblePreviewHeaderCell"));
274 }
275 
getSupportedServiceNames()276 uno::Sequence<rtl::OUString> SAL_CALL ScAccessiblePreviewHeaderCell::getSupportedServiceNames()
277 {
278     uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
279     sal_Int32 nOldSize(aSequence.getLength());
280     aSequence.realloc(nOldSize + 1);
281     ::rtl::OUString* pNames = aSequence.getArray();
282 
283     pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.AccessibleCellView"));
284 
285     return aSequence;
286 }
287 
288 //=====  XTypeProvider  =======================================================
289 
getTypes()290 uno::Sequence< uno::Type > SAL_CALL ScAccessiblePreviewHeaderCell::getTypes()
291 {
292     return comphelper::concatSequences(ScAccessiblePreviewHeaderCellImpl::getTypes(), ScAccessibleContextBase::getTypes());
293 }
294 
295 uno::Sequence<sal_Int8> SAL_CALL
getImplementationId(void)296     ScAccessiblePreviewHeaderCell::getImplementationId(void)
297 {
298     ScUnoGuard aGuard;
299     IsObjectValid();
300     static uno::Sequence<sal_Int8> aId;
301     if (aId.getLength() == 0)
302     {
303         aId.realloc (16);
304         rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
305     }
306     return aId;
307 }
308 
309 //====  internal  =========================================================
310 
GetBoundingBoxOnScreen() const311 Rectangle ScAccessiblePreviewHeaderCell::GetBoundingBoxOnScreen() const
312 {
313     Rectangle aCellRect;
314 
315     FillTableInfo();
316 
317     if (mpTableInfo)
318     {
319         const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[maCellPos.Col()];
320         const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[maCellPos.Row()];
321 
322         aCellRect = Rectangle( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
323     }
324 
325     if (mpViewShell)
326     {
327         Window* pWindow = mpViewShell->GetWindow();
328         if (pWindow)
329         {
330             Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
331             aCellRect.setX(aCellRect.getX() + aRect.getX());
332             aCellRect.setY(aCellRect.getY() + aRect.getY());
333         }
334     }
335     return aCellRect;
336 }
337 
GetBoundingBox() const338 Rectangle ScAccessiblePreviewHeaderCell::GetBoundingBox() const
339 {
340     FillTableInfo();
341 
342     if (mpTableInfo)
343     {
344         const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[maCellPos.Col()];
345         const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[maCellPos.Row()];
346 
347         Rectangle aCellRect( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
348         uno::Reference<XAccessible> xAccParent = const_cast<ScAccessiblePreviewHeaderCell*>(this)->getAccessibleParent();
349         if (xAccParent.is())
350         {
351             uno::Reference<XAccessibleContext> xAccParentContext = xAccParent->getAccessibleContext();
352             uno::Reference<XAccessibleComponent> xAccParentComp (xAccParentContext, uno::UNO_QUERY);
353             if (xAccParentComp.is())
354             {
355                 Rectangle aParentRect (VCLRectangle(xAccParentComp->getBounds()));
356                 aCellRect.setX(aCellRect.getX() - aParentRect.getX());
357                 aCellRect.setY(aCellRect.getY() - aParentRect.getY());
358             }
359         }
360         return aCellRect;
361     }
362     return Rectangle();
363 }
364 
createAccessibleDescription()365 rtl::OUString SAL_CALL ScAccessiblePreviewHeaderCell::createAccessibleDescription()
366 {
367     rtl::OUString sDescription = String(ScResId(STR_ACC_HEADERCELL_DESCR));
368     return sDescription;
369 }
370 
createAccessibleName()371 rtl::OUString SAL_CALL ScAccessiblePreviewHeaderCell::createAccessibleName()
372 {
373     rtl::OUString sName = String(ScResId(STR_ACC_HEADERCELL_NAME));
374 
375     if ( mbColumnHeader )
376     {
377         if ( mbRowHeader )
378         {
379             //! name for corner cell?
380 
381 //          sName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Column/Row Header"));
382         }
383         else
384         {
385             // name of column header
386             sName += ScColToAlpha( maCellPos.Col() );
387         }
388     }
389     else
390     {
391         // name of row header
392         sName += rtl::OUString::valueOf( (sal_Int32) ( maCellPos.Row() + 1 ) );
393     }
394 
395     return sName;
396 }
397 
IsDefunc(const uno::Reference<XAccessibleStateSet> & rxParentStates)398 sal_Bool ScAccessiblePreviewHeaderCell::IsDefunc( const uno::Reference<XAccessibleStateSet>& rxParentStates )
399 {
400     return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
401         (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
402 }
403 
CreateTextHelper()404 void ScAccessiblePreviewHeaderCell::CreateTextHelper()
405 {
406     if (!mpTextHelper)
407     {
408         ::std::auto_ptr < ScAccessibleTextData > pAccessiblePreviewHeaderCellTextData
409             (new ScAccessiblePreviewHeaderCellTextData(mpViewShell, String(getAccessibleName()), maCellPos, mbColumnHeader, mbRowHeader));
410         ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessiblePreviewHeaderCellTextData));
411 
412         mpTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource );
413         mpTextHelper->SetEventSource(this);
414     }
415 }
416 
FillTableInfo() const417 void ScAccessiblePreviewHeaderCell::FillTableInfo() const
418 {
419     if ( mpViewShell && !mpTableInfo )
420     {
421         Size aOutputSize;
422         Window* pWindow = mpViewShell->GetWindow();
423         if ( pWindow )
424             aOutputSize = pWindow->GetOutputSizePixel();
425         Point aPoint;
426         Rectangle aVisRect( aPoint, aOutputSize );
427 
428         mpTableInfo = new ScPreviewTableInfo;
429         mpViewShell->GetLocationData().GetTableInfo( aVisRect, *mpTableInfo );
430     }
431 }
432