1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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
,
57 ScAccessibleContextBase( rxParent
, AccessibleRole::TABLE_CELL
),
58 mpViewShell( pViewShell
),
60 maCellPos( rCellPos
),
61 mbColumnHeader( bIsColHdr
),
62 mbRowHeader( bIsRowHdr
)
65 mpViewShell
->AddAccessibilityObject(*this);
68 ScAccessiblePreviewHeaderCell::~ScAccessiblePreviewHeaderCell()
71 mpViewShell
->RemoveAccessibilityObject(*this);
74 void SAL_CALL
ScAccessiblePreviewHeaderCell::disposing()
76 SolarMutexGuard aGuard
;
79 mpViewShell
->RemoveAccessibilityObject(*this);
80 mpViewShell
= nullptr;
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
)
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
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()
119 ScAccessibleContextBase::acquire();
122 void SAL_CALL
ScAccessiblePreviewHeaderCell::release()
125 ScAccessibleContextBase::release();
128 //===== XAccessibleValue ================================================
130 uno::Any SAL_CALL
ScAccessiblePreviewHeaderCell::getCurrentValue()
132 SolarMutexGuard aGuard
;
137 fValue
= maCellPos
.Col();
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
150 uno::Any SAL_CALL
ScAccessiblePreviewHeaderCell::getMaximumValue()
152 SolarMutexGuard aGuard
;
156 ScDocument
& rDoc
= mpViewShell
->GetDocument();
158 fValue
= rDoc
.MaxCol();
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'
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
;
188 xRet
= mxTextHelper
->GetAt(rPoint
);
194 void SAL_CALL
ScAccessiblePreviewHeaderCell::grabFocus()
196 SolarMutexGuard aGuard
;
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
;
214 return mxTextHelper
->GetChildCount();
217 uno::Reference
< XAccessible
> SAL_CALL
ScAccessiblePreviewHeaderCell::getAccessibleChild(sal_Int64 nIndex
)
219 SolarMutexGuard aGuard
;
223 return mxTextHelper
->GetChild(nIndex
);
226 sal_Int64 SAL_CALL
ScAccessiblePreviewHeaderCell::getAccessibleIndexInParent()
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
;
246 nStateSet
|= AccessibleStateType::ENABLED
;
247 nStateSet
|= AccessibleStateType::MULTI_LINE
;
249 nStateSet
|= AccessibleStateType::SHOWING
;
250 nStateSet
|= AccessibleStateType::TRANSIENT
;
252 nStateSet
|= AccessibleStateType::VISIBLE
;
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
;
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
);
301 vcl::Window
* pWindow
= mpViewShell
->GetWindow();
304 tools::Rectangle aRect
= pWindow
->GetWindowExtentsRelative(nullptr);
305 aCellRect
.Move(aRect
.Left(), aRect
.Top());
311 tools::Rectangle
ScAccessiblePreviewHeaderCell::GetBoundingBox() const
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();
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());
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
)
350 //! name for corner cell?
352 // sName = "Column/Row Header";
356 // name of column header
357 sName
+= ScColToAlpha( maCellPos
.Col() );
362 // name of row header
363 sName
+= OUString::number( maCellPos
.Row() + 1 );
369 bool ScAccessiblePreviewHeaderCell::IsDefunc( sal_Int64 nParentStates
)
371 return ScAccessibleContextBase::IsDefunc() || (mpViewShell
== nullptr) || !getAccessibleParent().is() ||
372 (nParentStates
& AccessibleStateType::DEFUNC
);
375 void ScAccessiblePreviewHeaderCell::CreateTextHelper()
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
)
393 vcl::Window
* pWindow
= mpViewShell
->GetWindow();
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: */