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 0 : 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 0 : mpTableInfo( NULL )
88 : {
89 0 : if (mpViewShell)
90 0 : mpViewShell->AddAccessibilityObject(*this);
91 0 : }
92 :
93 0 : ScAccessiblePreviewHeaderCell::~ScAccessiblePreviewHeaderCell()
94 : {
95 0 : if (mpViewShell)
96 0 : mpViewShell->RemoveAccessibilityObject(*this);
97 0 : }
98 :
99 0 : void SAL_CALL ScAccessiblePreviewHeaderCell::disposing()
100 : {
101 0 : SolarMutexGuard aGuard;
102 0 : if (mpViewShell)
103 : {
104 0 : mpViewShell->RemoveAccessibilityObject(*this);
105 0 : mpViewShell = NULL;
106 : }
107 :
108 0 : if (mpTableInfo)
109 0 : DELETEZ (mpTableInfo);
110 :
111 0 : ScAccessibleContextBase::disposing();
112 0 : }
113 :
114 : //===== SfxListener =====================================================
115 :
116 0 : void ScAccessiblePreviewHeaderCell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
117 : {
118 0 : 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 0 : ScAccessibleContextBase::Notify(rBC, rHint);
136 0 : }
137 :
138 : //===== XInterface =====================================================
139 :
140 0 : uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::queryInterface( uno::Type const & rType )
141 : throw (uno::RuntimeException, std::exception)
142 : {
143 0 : uno::Any aAny (ScAccessiblePreviewHeaderCellImpl::queryInterface(rType));
144 0 : return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
145 : }
146 :
147 0 : void SAL_CALL ScAccessiblePreviewHeaderCell::acquire()
148 : throw ()
149 : {
150 0 : ScAccessibleContextBase::acquire();
151 0 : }
152 :
153 0 : void SAL_CALL ScAccessiblePreviewHeaderCell::release()
154 : throw ()
155 : {
156 0 : ScAccessibleContextBase::release();
157 0 : }
158 :
159 : //===== XAccessibleValue ================================================
160 :
161 0 : uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getCurrentValue() throw (uno::RuntimeException, std::exception)
162 : {
163 0 : SolarMutexGuard aGuard;
164 0 : IsObjectValid();
165 :
166 0 : double fValue(0.0);
167 0 : if (mbColumnHeader)
168 0 : fValue = maCellPos.Col();
169 : else
170 0 : fValue = maCellPos.Row();
171 :
172 0 : uno::Any aAny;
173 0 : aAny <<= fValue;
174 0 : return aAny;
175 : }
176 :
177 0 : 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 0 : return false;
182 : }
183 :
184 0 : uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getMaximumValue() throw (uno::RuntimeException, std::exception)
185 : {
186 0 : SolarMutexGuard aGuard;
187 0 : IsObjectValid();
188 :
189 0 : double fValue(0.0);
190 0 : if (mbColumnHeader)
191 0 : fValue = MAXCOL;
192 : else
193 0 : fValue = MAXROW;
194 0 : uno::Any aAny;
195 0 : aAny <<= fValue;
196 0 : return aAny;
197 : }
198 :
199 0 : uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getMinimumValue() throw (uno::RuntimeException, std::exception)
200 : {
201 0 : double fValue(0.0);
202 0 : uno::Any aAny;
203 0 : aAny <<= fValue;
204 0 : return aAny;
205 : }
206 :
207 : //===== XAccessibleComponent ============================================
208 :
209 0 : uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleAtPoint( const awt::Point& rPoint )
210 : throw (uno::RuntimeException, std::exception)
211 : {
212 0 : uno::Reference<XAccessible> xRet;
213 0 : if (containsPoint(rPoint))
214 : {
215 0 : SolarMutexGuard aGuard;
216 0 : IsObjectValid();
217 :
218 0 : if(!mpTextHelper)
219 0 : CreateTextHelper();
220 :
221 0 : xRet = mpTextHelper->GetAt(rPoint);
222 : }
223 :
224 0 : return xRet;
225 : }
226 :
227 0 : void SAL_CALL ScAccessiblePreviewHeaderCell::grabFocus() throw (uno::RuntimeException, std::exception)
228 : {
229 0 : SolarMutexGuard aGuard;
230 0 : IsObjectValid();
231 0 : if (getAccessibleParent().is())
232 : {
233 0 : uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
234 0 : if (xAccessibleComponent.is())
235 0 : xAccessibleComponent->grabFocus();
236 0 : }
237 0 : }
238 :
239 : //===== XAccessibleContext ==============================================
240 :
241 0 : sal_Int32 SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleChildCount() throw(uno::RuntimeException, std::exception)
242 : {
243 0 : SolarMutexGuard aGuard;
244 0 : IsObjectValid();
245 0 : if (!mpTextHelper)
246 0 : CreateTextHelper();
247 0 : return mpTextHelper->GetChildCount();
248 : }
249 :
250 0 : uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleChild(sal_Int32 nIndex)
251 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
252 : {
253 0 : SolarMutexGuard aGuard;
254 0 : IsObjectValid();
255 0 : if (!mpTextHelper)
256 0 : CreateTextHelper();
257 0 : return mpTextHelper->GetChild(nIndex);
258 : }
259 :
260 0 : sal_Int32 SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleIndexInParent() throw (uno::RuntimeException, std::exception)
261 : {
262 0 : return mnIndex;
263 : }
264 :
265 0 : uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleStateSet()
266 : throw(uno::RuntimeException, std::exception)
267 : {
268 0 : SolarMutexGuard aGuard;
269 :
270 0 : uno::Reference<XAccessibleStateSet> xParentStates;
271 0 : if (getAccessibleParent().is())
272 : {
273 0 : uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
274 0 : xParentStates = xParentContext->getAccessibleStateSet();
275 : }
276 0 : utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
277 0 : if (IsDefunc(xParentStates))
278 0 : pStateSet->AddState(AccessibleStateType::DEFUNC);
279 : else
280 : {
281 0 : pStateSet->AddState(AccessibleStateType::ENABLED);
282 0 : pStateSet->AddState(AccessibleStateType::MULTI_LINE);
283 0 : if (isShowing())
284 0 : pStateSet->AddState(AccessibleStateType::SHOWING);
285 0 : pStateSet->AddState(AccessibleStateType::TRANSIENT);
286 0 : if (isVisible())
287 0 : pStateSet->AddState(AccessibleStateType::VISIBLE);
288 : }
289 0 : return pStateSet;
290 : }
291 :
292 : //===== XServiceInfo ====================================================
293 :
294 0 : OUString SAL_CALL ScAccessiblePreviewHeaderCell::getImplementationName() throw(uno::RuntimeException, std::exception)
295 : {
296 0 : 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 0 : Rectangle ScAccessiblePreviewHeaderCell::GetBoundingBoxOnScreen() const throw (uno::RuntimeException, std::exception)
329 : {
330 0 : Rectangle aCellRect;
331 :
332 0 : FillTableInfo();
333 :
334 0 : if (mpTableInfo)
335 : {
336 0 : const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[maCellPos.Col()];
337 0 : const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[maCellPos.Row()];
338 :
339 0 : aCellRect = Rectangle( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
340 : }
341 :
342 0 : if (mpViewShell)
343 : {
344 0 : Window* pWindow = mpViewShell->GetWindow();
345 0 : if (pWindow)
346 : {
347 0 : Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
348 0 : aCellRect.setX(aCellRect.getX() + aRect.getX());
349 0 : aCellRect.setY(aCellRect.getY() + aRect.getY());
350 : }
351 : }
352 0 : return aCellRect;
353 : }
354 :
355 0 : Rectangle ScAccessiblePreviewHeaderCell::GetBoundingBox() const throw (uno::RuntimeException, std::exception)
356 : {
357 0 : FillTableInfo();
358 :
359 0 : if (mpTableInfo)
360 : {
361 0 : const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[maCellPos.Col()];
362 0 : const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[maCellPos.Row()];
363 :
364 0 : Rectangle aCellRect( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
365 0 : uno::Reference<XAccessible> xAccParent = const_cast<ScAccessiblePreviewHeaderCell*>(this)->getAccessibleParent();
366 0 : if (xAccParent.is())
367 : {
368 0 : uno::Reference<XAccessibleContext> xAccParentContext = xAccParent->getAccessibleContext();
369 0 : uno::Reference<XAccessibleComponent> xAccParentComp (xAccParentContext, uno::UNO_QUERY);
370 0 : if (xAccParentComp.is())
371 : {
372 0 : Rectangle aParentRect (VCLRectangle(xAccParentComp->getBounds()));
373 0 : aCellRect.setX(aCellRect.getX() - aParentRect.getX());
374 0 : aCellRect.setY(aCellRect.getY() - aParentRect.getY());
375 0 : }
376 : }
377 0 : return aCellRect;
378 : }
379 0 : return Rectangle();
380 : }
381 :
382 0 : OUString SAL_CALL ScAccessiblePreviewHeaderCell::createAccessibleDescription() throw(uno::RuntimeException)
383 : {
384 0 : OUString sDescription = OUString(ScResId(STR_ACC_HEADERCELL_DESCR));
385 0 : return sDescription;
386 : }
387 :
388 0 : OUString SAL_CALL ScAccessiblePreviewHeaderCell::createAccessibleName() throw(uno::RuntimeException, std::exception)
389 : {
390 0 : OUString sName = OUString(ScResId(STR_ACC_HEADERCELL_NAME));
391 :
392 0 : if ( mbColumnHeader )
393 : {
394 0 : if ( mbRowHeader )
395 : {
396 : //! name for corner cell?
397 :
398 : // sName = "Column/Row Header";
399 : }
400 : else
401 : {
402 : // name of column header
403 0 : sName += ScColToAlpha( maCellPos.Col() );
404 : }
405 : }
406 : else
407 : {
408 : // name of row header
409 0 : sName += OUString::number( ( maCellPos.Row() + 1 ) );
410 : }
411 :
412 0 : return sName;
413 : }
414 :
415 0 : bool ScAccessiblePreviewHeaderCell::IsDefunc( const uno::Reference<XAccessibleStateSet>& rxParentStates )
416 : {
417 0 : return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
418 0 : (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
419 : }
420 :
421 0 : void ScAccessiblePreviewHeaderCell::CreateTextHelper()
422 : {
423 0 : if (!mpTextHelper)
424 : {
425 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
426 : ::std::auto_ptr < ScAccessibleTextData > pAccessiblePreviewHeaderCellTextData
427 0 : (new ScAccessiblePreviewHeaderCellTextData(mpViewShell, OUString(getAccessibleName()), maCellPos, mbColumnHeader, mbRowHeader));
428 0 : ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessiblePreviewHeaderCellTextData));
429 : SAL_WNODEPRECATED_DECLARATIONS_POP
430 :
431 0 : mpTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource );
432 0 : mpTextHelper->SetEventSource(this);
433 : }
434 0 : }
435 :
436 0 : void ScAccessiblePreviewHeaderCell::FillTableInfo() const
437 : {
438 0 : if ( mpViewShell && !mpTableInfo )
439 : {
440 0 : Size aOutputSize;
441 0 : Window* pWindow = mpViewShell->GetWindow();
442 0 : if ( pWindow )
443 0 : aOutputSize = pWindow->GetOutputSizePixel();
444 0 : Point aPoint;
445 0 : Rectangle aVisRect( aPoint, aOutputSize );
446 :
447 0 : mpTableInfo = new ScPreviewTableInfo;
448 0 : mpViewShell->GetLocationData().GetTableInfo( aVisRect, *mpTableInfo );
449 : }
450 0 : }
451 :
452 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|