android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / core / access / acccell.cxx
blob8b15fa095545f0da992cc347d42fd4be8b619707
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/log.hxx>
21 #include <com/sun/star/accessibility/AccessibleRole.hpp>
22 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
23 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
24 #include <cppuhelper/supportsservice.hxx>
25 #include <cppuhelper/typeprovider.hxx>
26 #include <vcl/svapp.hxx>
27 #include <cellfrm.hxx>
28 #include <tabfrm.hxx>
29 #include <swtable.hxx>
30 #include <crsrsh.hxx>
31 #include <viscrs.hxx>
32 #include "accfrmobj.hxx"
33 #include "accfrmobjslist.hxx"
34 #include <frmfmt.hxx>
35 #include <cellatr.hxx>
36 #include <accmap.hxx>
37 #include "acccell.hxx"
39 #include <cfloat>
40 #include <string_view>
42 #include <editeng/brushitem.hxx>
43 #include <swatrset.hxx>
44 #include <frmatr.hxx>
45 #include "acctable.hxx"
47 using namespace ::com::sun::star;
48 using namespace ::com::sun::star::accessibility;
49 using namespace sw::access;
51 constexpr OUStringLiteral sImplementationName = u"com.sun.star.comp.Writer.SwAccessibleCellView";
53 bool SwAccessibleCell::IsSelected()
55 bool bRet = false;
57 assert(GetMap());
58 const SwViewShell *pVSh = GetMap()->GetShell();
59 assert(pVSh);
60 if( auto pCSh = dynamic_cast<const SwCursorShell*>(pVSh) )
62 if( pCSh->IsTableMode() )
64 const SwCellFrame *pCFrame =
65 static_cast< const SwCellFrame * >( GetFrame() );
66 SwTableBox *pBox =
67 const_cast< SwTableBox *>( pCFrame->GetTabBox() );
68 SwSelBoxes const& rBoxes(pCSh->GetTableCursor()->GetSelectedBoxes());
69 bRet = rBoxes.find(pBox) != rBoxes.end();
73 return bRet;
76 void SwAccessibleCell::GetStates( sal_Int64& rStateSet )
78 SwAccessibleContext::GetStates( rStateSet );
80 // SELECTABLE
81 const SwViewShell *pVSh = GetMap()->GetShell();
82 assert(pVSh);
83 if( dynamic_cast<const SwCursorShell*>( pVSh) != nullptr )
84 rStateSet |= AccessibleStateType::SELECTABLE;
85 //Add resizable state to table cell.
86 rStateSet |= AccessibleStateType::RESIZABLE;
88 if (IsDisposing()) // tdf#135098
89 return;
91 // SELECTED
92 if( IsSelected() )
94 rStateSet |= AccessibleStateType::SELECTED;
95 SAL_WARN_IF(!m_bIsSelected, "sw.a11y", "bSelected out of sync");
96 ::rtl::Reference < SwAccessibleContext > xThis( this );
97 GetMap()->SetCursorContext( xThis );
101 SwAccessibleCell::SwAccessibleCell(std::shared_ptr<SwAccessibleMap> const& pInitMap,
102 const SwCellFrame *pCellFrame )
103 : SwAccessibleContext( pInitMap, AccessibleRole::TABLE_CELL, pCellFrame )
104 , m_aSelectionHelper( *this )
105 , m_bIsSelected( false )
107 OUString sBoxName( pCellFrame->GetTabBox()->GetName() );
108 SetName( sBoxName );
110 m_bIsSelected = IsSelected();
112 css::uno::Reference<css::accessibility::XAccessible> xTableReference(
113 getAccessibleParentImpl());
114 css::uno::Reference<css::accessibility::XAccessibleContext> xContextTable(
115 xTableReference, css::uno::UNO_QUERY);
116 SAL_WARN_IF(
117 (!xContextTable.is()
118 || xContextTable->getAccessibleRole() != AccessibleRole::TABLE),
119 "sw.a11y", "bad accessible context");
120 m_pAccTable = static_cast<SwAccessibleTable *>(xTableReference.get());
123 bool SwAccessibleCell::InvalidateMyCursorPos()
125 bool bNew = IsSelected();
126 bool bOld;
128 std::scoped_lock aGuard( m_Mutex );
129 bOld = m_bIsSelected;
130 m_bIsSelected = bNew;
132 if( bNew )
134 // remember that object as the one that has the caret. This is
135 // necessary to notify that object if the cursor leaves it.
136 ::rtl::Reference < SwAccessibleContext > xThis( this );
137 GetMap()->SetCursorContext( xThis );
140 bool bChanged = bOld != bNew;
141 if( bChanged )
143 FireStateChangedEvent( AccessibleStateType::SELECTED, bNew );
144 if (m_pAccTable.is())
146 m_pAccTable->AddSelectionCell(this,bNew);
149 return bChanged;
152 bool SwAccessibleCell::InvalidateChildrenCursorPos( const SwFrame *pFrame )
154 bool bChanged = false;
156 const SwAccessibleChildSList aVisList( GetVisArea(), *pFrame, *GetMap() );
157 SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
158 while( aIter != aVisList.end() )
160 const SwAccessibleChild& rLower = *aIter;
161 const SwFrame *pLower = rLower.GetSwFrame();
162 if( pLower )
164 if( rLower.IsAccessible( GetMap()->GetShell()->IsPreview() ) )
166 ::rtl::Reference< SwAccessibleContext > xAccImpl(
167 GetMap()->GetContextImpl( pLower, false ) );
168 if( xAccImpl.is() )
170 assert(xAccImpl->GetFrame()->IsCellFrame());
171 bChanged = static_cast< SwAccessibleCell *>(
172 xAccImpl.get() )->InvalidateMyCursorPos();
174 else
175 bChanged = true; // If the context is not know we
176 // don't know whether the selection
177 // changed or not.
179 else
181 // This is a box with sub rows.
182 bChanged |= InvalidateChildrenCursorPos( pLower );
185 ++aIter;
188 return bChanged;
191 void SwAccessibleCell::InvalidateCursorPos_()
193 if (IsSelected())
195 const SwAccessibleChild aChild( GetChild( *(GetMap()), 0 ) );
196 if( aChild.IsValid() && aChild.GetSwFrame() )
198 ::rtl::Reference < SwAccessibleContext > xChildImpl( GetMap()->GetContextImpl( aChild.GetSwFrame()) );
199 if (xChildImpl.is())
201 AccessibleEventObject aEvent;
202 aEvent.EventId = AccessibleEventId::STATE_CHANGED;
203 aEvent.NewValue <<= AccessibleStateType::FOCUSED;
204 xChildImpl->FireAccessibleEvent( aEvent );
209 const SwFrame *pParent = GetParent( SwAccessibleChild(GetFrame()), IsInPagePreview() );
210 assert(pParent->IsTabFrame());
211 const SwTabFrame *pTabFrame = static_cast< const SwTabFrame * >( pParent );
212 if( pTabFrame->IsFollow() )
213 pTabFrame = pTabFrame->FindMaster();
215 while( pTabFrame )
217 InvalidateChildrenCursorPos( pTabFrame );
218 pTabFrame = pTabFrame->GetFollow();
220 if (m_pAccTable.is())
222 m_pAccTable->FireSelectionEvent();
226 bool SwAccessibleCell::HasCursor()
228 std::scoped_lock aGuard( m_Mutex );
229 return m_bIsSelected;
232 SwAccessibleCell::~SwAccessibleCell()
236 OUString SAL_CALL SwAccessibleCell::getAccessibleDescription()
238 return GetName();
241 OUString SAL_CALL SwAccessibleCell::getImplementationName()
243 return sImplementationName;
246 sal_Bool SAL_CALL SwAccessibleCell::supportsService(const OUString& sTestServiceName)
248 return cppu::supportsService(this, sTestServiceName);
251 uno::Sequence< OUString > SAL_CALL SwAccessibleCell::getSupportedServiceNames()
253 return { "com.sun.star.table.AccessibleCellView", sAccessibleServiceName };
256 void SwAccessibleCell::Dispose(bool bRecursive, bool bCanSkipInvisible)
258 const SwFrame *pParent = GetParent( SwAccessibleChild(GetFrame()), IsInPagePreview() );
259 ::rtl::Reference< SwAccessibleContext > xAccImpl(
260 GetMap()->GetContextImpl( pParent, false ) );
261 if( xAccImpl.is() )
262 xAccImpl->DisposeChild(SwAccessibleChild(GetFrame()), bRecursive, bCanSkipInvisible);
263 SwAccessibleContext::Dispose( bRecursive );
266 void SwAccessibleCell::InvalidatePosOrSize( const SwRect& rOldBox )
268 const SwFrame *pParent = GetParent( SwAccessibleChild(GetFrame()), IsInPagePreview() );
269 ::rtl::Reference< SwAccessibleContext > xAccImpl(
270 GetMap()->GetContextImpl( pParent, false ) );
271 if( xAccImpl.is() )
272 xAccImpl->InvalidateChildPosOrSize( SwAccessibleChild(GetFrame()), rOldBox );
273 SwAccessibleContext::InvalidatePosOrSize( rOldBox );
276 // XAccessibleInterface
278 uno::Any SwAccessibleCell::queryInterface( const uno::Type& rType )
280 if (rType == cppu::UnoType<XAccessibleExtendedAttributes>::get())
282 uno::Any aR;
283 aR <<= uno::Reference<XAccessibleExtendedAttributes>(this);
284 return aR;
287 if (rType == cppu::UnoType<XAccessibleSelection>::get())
289 uno::Any aR;
290 aR <<= uno::Reference<XAccessibleSelection>(this);
291 return aR;
293 if ( rType == ::cppu::UnoType<XAccessibleValue>::get() )
295 uno::Reference<XAccessibleValue> xValue = this;
296 uno::Any aRet;
297 aRet <<= xValue;
298 return aRet;
300 else
302 return SwAccessibleContext::queryInterface( rType );
306 // XTypeProvider
307 uno::Sequence< uno::Type > SAL_CALL SwAccessibleCell::getTypes()
309 return cppu::OTypeCollection(
310 ::cppu::UnoType<XAccessibleValue>::get(),
311 SwAccessibleContext::getTypes() ).getTypes();
314 uno::Sequence< sal_Int8 > SAL_CALL SwAccessibleCell::getImplementationId()
316 return css::uno::Sequence<sal_Int8>();
319 // XAccessibleValue
321 SwFrameFormat* SwAccessibleCell::GetTableBoxFormat() const
323 assert(GetFrame());
324 assert(GetFrame()->IsCellFrame());
326 const SwCellFrame* pCellFrame = static_cast<const SwCellFrame*>( GetFrame() );
327 return pCellFrame->GetTabBox()->GetFrameFormat();
330 //Implement TableCell currentValue
331 uno::Any SwAccessibleCell::getCurrentValue( )
333 SolarMutexGuard aGuard;
335 ThrowIfDisposed();
337 return uno::Any( GetTableBoxFormat()->GetTableBoxValue().GetValue() );
340 sal_Bool SwAccessibleCell::setCurrentValue( const uno::Any& aNumber )
342 SolarMutexGuard aGuard;
344 ThrowIfDisposed();
346 double fValue = 0;
347 bool bValid = (aNumber >>= fValue);
348 if( bValid )
350 SwTableBoxValue aValue( fValue );
351 GetTableBoxFormat()->SetFormatAttr( aValue );
353 return bValid;
356 uno::Any SwAccessibleCell::getMaximumValue( )
358 return uno::Any(DBL_MAX);
361 uno::Any SwAccessibleCell::getMinimumValue( )
363 return uno::Any(-DBL_MAX);
366 uno::Any SwAccessibleCell::getMinimumIncrement( )
368 return uno::Any();
371 css::uno::Any SAL_CALL SwAccessibleCell::getExtendedAttributes()
373 SolarMutexGuard g;
375 css::uno::Any strRet;
376 SwFrameFormat *pFrameFormat = GetTableBoxFormat();
377 assert(pFrameFormat);
379 const SwTableBoxFormula& tbl_formula = pFrameFormat->GetTableBoxFormula();
381 OUString strFormula = tbl_formula.GetFormula()
382 .replaceAll(u"\\", u"\\\\")
383 .replaceAll(u";", u"\\;")
384 .replaceAll(u"=", u"\\=")
385 .replaceAll(u",", u"\\,")
386 .replaceAll(u":", u"\\:");
387 OUString strFor = "Formula:" + strFormula + ";";
388 strRet <<= strFor;
390 return strRet;
393 sal_Int32 SAL_CALL SwAccessibleCell::getBackground()
395 SolarMutexGuard g;
397 const SvxBrushItem &rBack = GetFrame()->GetAttrSet()->GetBackground();
398 Color crBack = rBack.GetColor();
400 if (COL_AUTO == crBack)
402 uno::Reference<XAccessible> xAccDoc = getAccessibleParent();
403 if (xAccDoc.is())
405 uno::Reference<XAccessibleComponent> xComponentDoc(xAccDoc, uno::UNO_QUERY);
406 if (xComponentDoc.is())
408 crBack = Color(ColorTransparency, xComponentDoc->getBackground());
412 return sal_Int32(crBack);
415 // XAccessibleSelection
416 void SwAccessibleCell::selectAccessibleChild(
417 sal_Int64 nChildIndex )
419 m_aSelectionHelper.selectAccessibleChild(nChildIndex);
422 sal_Bool SwAccessibleCell::isAccessibleChildSelected(
423 sal_Int64 nChildIndex )
425 return m_aSelectionHelper.isAccessibleChildSelected(nChildIndex);
428 void SwAccessibleCell::clearAccessibleSelection( )
432 void SwAccessibleCell::selectAllAccessibleChildren( )
434 m_aSelectionHelper.selectAllAccessibleChildren();
437 sal_Int64 SwAccessibleCell::getSelectedAccessibleChildCount( )
439 return m_aSelectionHelper.getSelectedAccessibleChildCount();
442 uno::Reference<XAccessible> SwAccessibleCell::getSelectedAccessibleChild(
443 sal_Int64 nSelectedChildIndex )
445 return m_aSelectionHelper.getSelectedAccessibleChild(nSelectedChildIndex);
448 void SwAccessibleCell::deselectAccessibleChild(
449 sal_Int64 nSelectedChildIndex )
451 m_aSelectionHelper.deselectAccessibleChild(nSelectedChildIndex);
454 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */