calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / sc / source / ui / Accessibility / AccessiblePreviewHeaderCell.cxx
blobc7b767d0eb0b07d787c3fb53aa5a8d32fbf1c62c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
22 #include <tools/gen.hxx>
23 #include <AccessibleText.hxx>
24 #include <editsrc.hxx>
25 #include <svx/AccessibleTextHelper.hxx>
26 #include <AccessiblePreviewHeaderCell.hxx>
27 #include <prevwsh.hxx>
28 #include <prevloc.hxx>
29 #include <strings.hxx>
31 #include <com/sun/star/accessibility/AccessibleRole.hpp>
32 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
33 #include <comphelper/sequence.hxx>
35 #include <vcl/window.hxx>
36 #include <vcl/svapp.hxx>
37 #include <svl/hint.hxx>
38 #include <toolkit/helper/convert.hxx>
40 #ifdef indices
41 #undef indices
42 #endif
44 #ifdef extents
45 #undef extents
46 #endif
48 using namespace ::com::sun::star;
49 using namespace ::com::sun::star::accessibility;
51 //===== internal ============================================================
53 ScAccessiblePreviewHeaderCell::ScAccessiblePreviewHeaderCell( const css::uno::Reference<css::accessibility::XAccessible>& rxParent,
54 ScPreviewShell* pViewShell,
55 const ScAddress& rCellPos, bool bIsColHdr, bool bIsRowHdr,
56 sal_Int32 nIndex ) :
57 ScAccessibleContextBase( rxParent, AccessibleRole::TABLE_CELL ),
58 mpViewShell( pViewShell ),
59 mnIndex( nIndex ),
60 maCellPos( rCellPos ),
61 mbColumnHeader( bIsColHdr ),
62 mbRowHeader( bIsRowHdr )
64 if (mpViewShell)
65 mpViewShell->AddAccessibilityObject(*this);
68 ScAccessiblePreviewHeaderCell::~ScAccessiblePreviewHeaderCell()
70 if (mpViewShell)
71 mpViewShell->RemoveAccessibilityObject(*this);
74 void SAL_CALL ScAccessiblePreviewHeaderCell::disposing()
76 SolarMutexGuard aGuard;
77 if (mpViewShell)
79 mpViewShell->RemoveAccessibilityObject(*this);
80 mpViewShell = nullptr;
83 mpTableInfo.reset();
85 ScAccessibleContextBase::disposing();
88 //===== SfxListener =====================================================
90 void ScAccessiblePreviewHeaderCell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
92 const SfxHintId nId = rHint.GetId();
93 if (nId == SfxHintId::ScAccVisAreaChanged)
95 if (mxTextHelper)
96 mxTextHelper->UpdateChildren();
98 else if ( nId == SfxHintId::DataChanged )
100 // column / row layout may change with any document change,
101 // so it must be invalidated
102 mpTableInfo.reset();
105 ScAccessibleContextBase::Notify(rBC, rHint);
108 //===== XInterface =====================================================
110 uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::queryInterface( uno::Type const & rType )
112 uno::Any aAny (ScAccessiblePreviewHeaderCellImpl::queryInterface(rType));
113 return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
116 void SAL_CALL ScAccessiblePreviewHeaderCell::acquire()
117 noexcept
119 ScAccessibleContextBase::acquire();
122 void SAL_CALL ScAccessiblePreviewHeaderCell::release()
123 noexcept
125 ScAccessibleContextBase::release();
128 //===== XAccessibleValue ================================================
130 uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getCurrentValue()
132 SolarMutexGuard aGuard;
133 IsObjectValid();
135 double fValue(0.0);
136 if (mbColumnHeader)
137 fValue = maCellPos.Col();
138 else
139 fValue = maCellPos.Row();
141 return uno::Any(fValue);
144 sal_Bool SAL_CALL ScAccessiblePreviewHeaderCell::setCurrentValue( const uno::Any& /* aNumber */ )
146 // it is not possible to set a value
147 return false;
150 uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getMaximumValue()
152 SolarMutexGuard aGuard;
153 IsObjectValid();
155 double fValue(0.0);
156 ScDocument& rDoc = mpViewShell->GetDocument();
157 if (mbColumnHeader)
158 fValue = rDoc.MaxCol();
159 else
160 fValue = rDoc.MaxRow();
161 return uno::Any(fValue);
164 uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getMinimumValue()
166 return uno::Any(0.0);
169 uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getMinimumIncrement()
171 // value can't be changed, s. 'setCurrentValue'
172 return uno::Any();
175 //===== XAccessibleComponent ============================================
177 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleAtPoint( const awt::Point& rPoint )
179 uno::Reference<XAccessible> xRet;
180 if (containsPoint(rPoint))
182 SolarMutexGuard aGuard;
183 IsObjectValid();
185 if(!mxTextHelper)
186 CreateTextHelper();
188 xRet = mxTextHelper->GetAt(rPoint);
191 return xRet;
194 void SAL_CALL ScAccessiblePreviewHeaderCell::grabFocus()
196 SolarMutexGuard aGuard;
197 IsObjectValid();
198 if (getAccessibleParent().is())
200 uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
201 if (xAccessibleComponent.is())
202 xAccessibleComponent->grabFocus();
206 //===== XAccessibleContext ==============================================
208 sal_Int64 SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleChildCount()
210 SolarMutexGuard aGuard;
211 IsObjectValid();
212 if (!mxTextHelper)
213 CreateTextHelper();
214 return mxTextHelper->GetChildCount();
217 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleChild(sal_Int64 nIndex)
219 SolarMutexGuard aGuard;
220 IsObjectValid();
221 if (!mxTextHelper)
222 CreateTextHelper();
223 return mxTextHelper->GetChild(nIndex);
226 sal_Int64 SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleIndexInParent()
228 return mnIndex;
231 sal_Int64 SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleStateSet()
233 SolarMutexGuard aGuard;
235 sal_Int64 nParentStates = 0;
236 if (getAccessibleParent().is())
238 uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
239 nParentStates = xParentContext->getAccessibleStateSet();
241 sal_Int64 nStateSet = 0;
242 if (IsDefunc(nParentStates))
243 nStateSet |= AccessibleStateType::DEFUNC;
244 else
246 nStateSet |= AccessibleStateType::ENABLED;
247 nStateSet |= AccessibleStateType::MULTI_LINE;
248 if (isShowing())
249 nStateSet |= AccessibleStateType::SHOWING;
250 nStateSet |= AccessibleStateType::TRANSIENT;
251 if (isVisible())
252 nStateSet |= AccessibleStateType::VISIBLE;
254 return nStateSet;
257 //===== XServiceInfo ====================================================
259 OUString SAL_CALL ScAccessiblePreviewHeaderCell::getImplementationName()
261 return "ScAccessiblePreviewHeaderCell";
264 uno::Sequence<OUString> SAL_CALL ScAccessiblePreviewHeaderCell::getSupportedServiceNames()
266 const css::uno::Sequence<OUString> vals { "com.sun.star.table.AccessibleCellView" };
267 return comphelper::concatSequences(ScAccessibleContextBase::getSupportedServiceNames(), vals);
270 //===== XTypeProvider =======================================================
272 uno::Sequence< uno::Type > SAL_CALL ScAccessiblePreviewHeaderCell::getTypes()
274 return comphelper::concatSequences(ScAccessiblePreviewHeaderCellImpl::getTypes(), ScAccessibleContextBase::getTypes());
277 uno::Sequence<sal_Int8> SAL_CALL
278 ScAccessiblePreviewHeaderCell::getImplementationId()
280 return css::uno::Sequence<sal_Int8>();
283 //==== internal =========================================================
285 tools::Rectangle ScAccessiblePreviewHeaderCell::GetBoundingBoxOnScreen() const
287 tools::Rectangle aCellRect;
289 FillTableInfo();
291 if (mpTableInfo)
293 const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[maCellPos.Col()];
294 const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[maCellPos.Row()];
296 aCellRect = tools::Rectangle( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
299 if (mpViewShell)
301 vcl::Window* pWindow = mpViewShell->GetWindow();
302 if (pWindow)
304 tools::Rectangle aRect = pWindow->GetWindowExtentsRelative(nullptr);
305 aCellRect.Move(aRect.Left(), aRect.Top());
308 return aCellRect;
311 tools::Rectangle ScAccessiblePreviewHeaderCell::GetBoundingBox() const
313 FillTableInfo();
315 if (mpTableInfo)
317 const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[maCellPos.Col()];
318 const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[maCellPos.Row()];
320 tools::Rectangle aCellRect( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
321 uno::Reference<XAccessible> xAccParent = const_cast<ScAccessiblePreviewHeaderCell*>(this)->getAccessibleParent();
322 if (xAccParent.is())
324 uno::Reference<XAccessibleContext> xAccParentContext = xAccParent->getAccessibleContext();
325 uno::Reference<XAccessibleComponent> xAccParentComp (xAccParentContext, uno::UNO_QUERY);
326 if (xAccParentComp.is())
328 tools::Rectangle aParentRect (VCLRectangle(xAccParentComp->getBounds()));
329 aCellRect.Move(-aParentRect.Left(), -aParentRect.Top());
332 return aCellRect;
334 return tools::Rectangle();
337 OUString ScAccessiblePreviewHeaderCell::createAccessibleDescription()
339 return STR_ACC_HEADERCELL_DESCR;
342 OUString ScAccessiblePreviewHeaderCell::createAccessibleName()
344 OUString sName = STR_ACC_HEADERCELL_NAME;
346 if ( mbColumnHeader )
348 if ( mbRowHeader )
350 //! name for corner cell?
352 // sName = "Column/Row Header";
354 else
356 // name of column header
357 sName += ScColToAlpha( maCellPos.Col() );
360 else
362 // name of row header
363 sName += OUString::number( maCellPos.Row() + 1 );
366 return sName;
369 bool ScAccessiblePreviewHeaderCell::IsDefunc( sal_Int64 nParentStates )
371 return ScAccessibleContextBase::IsDefunc() || (mpViewShell == nullptr) || !getAccessibleParent().is() ||
372 (nParentStates & AccessibleStateType::DEFUNC);
375 void ScAccessiblePreviewHeaderCell::CreateTextHelper()
377 if (!mxTextHelper)
379 mxTextHelper.reset( new ::accessibility::AccessibleTextHelper(
380 std::make_unique<ScAccessibilityEditSource>(
381 std::make_unique<ScAccessiblePreviewHeaderCellTextData>(
382 mpViewShell, getAccessibleName(), maCellPos,
383 mbColumnHeader, mbRowHeader))) );
384 mxTextHelper->SetEventSource(this);
388 void ScAccessiblePreviewHeaderCell::FillTableInfo() const
390 if ( mpViewShell && !mpTableInfo )
392 Size aOutputSize;
393 vcl::Window* pWindow = mpViewShell->GetWindow();
394 if ( pWindow )
395 aOutputSize = pWindow->GetOutputSizePixel();
396 tools::Rectangle aVisRect( Point(), aOutputSize );
398 mpTableInfo.reset( new ScPreviewTableInfo );
399 mpViewShell->GetLocationData().GetTableInfo( aVisRect, *mpTableInfo );
403 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */