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