LibreOffice Module sw (master)  1
acccell.cxx
Go to the documentation of this file.
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 #include <osl/mutex.hxx>
21 #include <sal/log.hxx>
22 #include <com/sun/star/accessibility/AccessibleRole.hpp>
23 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
24 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
28 #include <vcl/svapp.hxx>
29 #include <cellfrm.hxx>
30 #include <tabfrm.hxx>
31 #include <swtable.hxx>
32 #include <crsrsh.hxx>
33 #include <viscrs.hxx>
34 #include "accfrmobj.hxx"
35 #include "accfrmobjslist.hxx"
36 #include <frmfmt.hxx>
37 #include <cellatr.hxx>
38 #include <accmap.hxx>
39 #include "acccell.hxx"
40 
41 #include <cfloat>
42 #include <limits.h>
43 
44 #include <ndtxt.hxx>
45 #include <editeng/brushitem.hxx>
46 #include <swatrset.hxx>
47 #include <frmatr.hxx>
48 #include "acctable.hxx"
49 
50 using namespace ::com::sun::star;
51 using namespace ::com::sun::star::accessibility;
52 using namespace sw::access;
53 
54 const sal_Char sImplementationName[] = "com.sun.star.comp.Writer.SwAccessibleCellView";
55 
57 {
58  bool bRet = false;
59 
60  assert(GetMap());
61  const SwViewShell *pVSh = GetMap()->GetShell();
62  assert(pVSh);
63  if( auto pCSh = dynamic_cast<const SwCursorShell*>(pVSh) )
64  {
65  if( pCSh->IsTableMode() )
66  {
67  const SwCellFrame *pCFrame =
68  static_cast< const SwCellFrame * >( GetFrame() );
69  SwTableBox *pBox =
70  const_cast< SwTableBox *>( pCFrame->GetTabBox() );
71  SwSelBoxes const& rBoxes(pCSh->GetTableCursor()->GetSelectedBoxes());
72  bRet = rBoxes.find(pBox) != rBoxes.end();
73  }
74  }
75 
76  return bRet;
77 }
78 
80 {
81  SwAccessibleContext::GetStates( rStateSet );
82 
83  // SELECTABLE
84  const SwViewShell *pVSh = GetMap()->GetShell();
85  assert(pVSh);
86  if( dynamic_cast<const SwCursorShell*>( pVSh) != nullptr )
87  rStateSet.AddState( AccessibleStateType::SELECTABLE );
88  //Add resizable state to table cell.
89  rStateSet.AddState( AccessibleStateType::RESIZABLE );
90 
91  // SELECTED
92  if( IsSelected() )
93  {
94  rStateSet.AddState( AccessibleStateType::SELECTED );
95  SAL_WARN_IF(!m_bIsSelected, "sw.a11y", "bSelected out of sync");
97  GetMap()->SetCursorContext( xThis );
98  }
99 }
100 
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 )
106 {
107  OUString sBoxName( pCellFrame->GetTabBox()->GetName() );
108  SetName( sBoxName );
109 
111 
112  css::uno::Reference<css::accessibility::XAccessible> xTableReference(
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());
121 }
122 
124 {
125  bool bNew = IsSelected();
126  bool bOld;
127  {
128  osl::MutexGuard aGuard( m_Mutex );
129  bOld = m_bIsSelected;
130  m_bIsSelected = bNew;
131  }
132  if( bNew )
133  {
134  // remember that object as the one that has the caret. This is
135  // necessary to notify that object if the cursor leaves it.
137  GetMap()->SetCursorContext( xThis );
138  }
139 
140  bool bChanged = bOld != bNew;
141  if( bChanged )
142  {
143  FireStateChangedEvent( AccessibleStateType::SELECTED, bNew );
144  if (m_pAccTable.is())
145  {
146  m_pAccTable->AddSelectionCell(this,bNew);
147  }
148  }
149  return bChanged;
150 }
151 
153 {
154  bool bChanged = false;
155 
156  const SwAccessibleChildSList aVisList( GetVisArea(), *pFrame, *GetMap() );
157  SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
158  while( aIter != aVisList.end() )
159  {
160  const SwAccessibleChild& rLower = *aIter;
161  const SwFrame *pLower = rLower.GetSwFrame();
162  if( pLower )
163  {
164  if( rLower.IsAccessible( GetMap()->GetShell()->IsPreview() ) )
165  {
167  GetMap()->GetContextImpl( pLower, false ) );
168  if( xAccImpl.is() )
169  {
170  assert(xAccImpl->GetFrame()->IsCellFrame());
171  bChanged = static_cast< SwAccessibleCell *>(
172  xAccImpl.get() )->InvalidateMyCursorPos();
173  }
174  else
175  bChanged = true; // If the context is not know we
176  // don't know whether the selection
177  // changed or not.
178  }
179  else
180  {
181  // This is a box with sub rows.
182  bChanged |= InvalidateChildrenCursorPos( pLower );
183  }
184  }
185  ++aIter;
186  }
187 
188  return bChanged;
189 }
190 
192 {
193  if (IsSelected())
194  {
195  const SwAccessibleChild aChild( GetChild( *(GetMap()), 0 ) );
196  if( aChild.IsValid() && aChild.GetSwFrame() )
197  {
198  ::rtl::Reference < SwAccessibleContext > xChildImpl( GetMap()->GetContextImpl( aChild.GetSwFrame()) );
199  if (xChildImpl.is())
200  {
201  AccessibleEventObject aEvent;
202  aEvent.EventId = AccessibleEventId::STATE_CHANGED;
203  aEvent.NewValue <<= AccessibleStateType::FOCUSED;
204  xChildImpl->FireAccessibleEvent( aEvent );
205  }
206  }
207  }
208 
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();
214 
215  while( pTabFrame )
216  {
217  InvalidateChildrenCursorPos( pTabFrame );
218  pTabFrame = pTabFrame->GetFollow();
219  }
220  if (m_pAccTable.is())
221  {
222  m_pAccTable->FireSelectionEvent();
223  }
224 }
225 
227 {
228  osl::MutexGuard aGuard( m_Mutex );
229  return m_bIsSelected;
230 }
231 
233 {
234 }
235 
237 {
238  return GetName();
239 }
240 
242 {
243  return OUString(sImplementationName);
244 }
245 
246 sal_Bool SAL_CALL SwAccessibleCell::supportsService(const OUString& sTestServiceName)
247 {
248  return cppu::supportsService(this, sTestServiceName);
249 }
250 
251 uno::Sequence< OUString > SAL_CALL SwAccessibleCell::getSupportedServiceNames()
252 {
253  uno::Sequence< OUString > aRet(2);
254  OUString* pArray = aRet.getArray();
255  pArray[0] = "com.sun.star.table.AccessibleCellView";
256  pArray[1] = sAccessibleServiceName;
257  return aRet;
258 }
259 
260 void SwAccessibleCell::Dispose(bool bRecursive, bool bCanSkipInvisible)
261 {
262  const SwFrame *pParent = GetParent( SwAccessibleChild(GetFrame()), IsInPagePreview() );
264  GetMap()->GetContextImpl( pParent, false ) );
265  if( xAccImpl.is() )
266  xAccImpl->DisposeChild(SwAccessibleChild(GetFrame()), bRecursive, bCanSkipInvisible);
267  SwAccessibleContext::Dispose( bRecursive );
268 }
269 
271 {
272  const SwFrame *pParent = GetParent( SwAccessibleChild(GetFrame()), IsInPagePreview() );
274  GetMap()->GetContextImpl( pParent, false ) );
275  if( xAccImpl.is() )
276  xAccImpl->InvalidateChildPosOrSize( SwAccessibleChild(GetFrame()), rOldBox );
278 }
279 
280 // XAccessibleInterface
281 
283 {
285  {
286  uno::Any aR;
287  aR <<= uno::Reference<XAccessibleExtendedAttributes>(this);
288  return aR;
289  }
290 
292  {
293  uno::Any aR;
294  aR <<= uno::Reference<XAccessibleSelection>(this);
295  return aR;
296  }
297  if ( rType == ::cppu::UnoType<XAccessibleValue>::get() )
298  {
299  uno::Reference<XAccessibleValue> xValue = this;
300  uno::Any aRet;
301  aRet <<= xValue;
302  return aRet;
303  }
304  else
305  {
306  return SwAccessibleContext::queryInterface( rType );
307  }
308 }
309 
310 // XTypeProvider
311 uno::Sequence< uno::Type > SAL_CALL SwAccessibleCell::getTypes()
312 {
313  return cppu::OTypeCollection(
315  SwAccessibleContext::getTypes() ).getTypes();
316 }
317 
318 uno::Sequence< sal_Int8 > SAL_CALL SwAccessibleCell::getImplementationId()
319 {
320  return css::uno::Sequence<sal_Int8>();
321 }
322 
323 // XAccessibleValue
324 
326 {
327  assert(GetFrame());
328  assert(GetFrame()->IsCellFrame());
329 
330  const SwCellFrame* pCellFrame = static_cast<const SwCellFrame*>( GetFrame() );
331  return pCellFrame->GetTabBox()->GetFrameFormat();
332 }
333 
334 //Implement TableCell currentValue
336 {
337  SolarMutexGuard aGuard;
338 
339  ThrowIfDisposed();
340 
341  return uno::Any( GetTableBoxFormat()->GetTableBoxValue().GetValue() );
342 }
343 
345 {
346  SolarMutexGuard aGuard;
347 
348  ThrowIfDisposed();
349 
350  double fValue = 0;
351  bool bValid = (aNumber >>= fValue);
352  if( bValid )
353  {
354  SwTableBoxValue aValue( fValue );
355  GetTableBoxFormat()->SetFormatAttr( aValue );
356  }
357  return bValid;
358 }
359 
361 {
362  return uno::Any(DBL_MAX);
363 }
364 
366 {
367  return uno::Any(-DBL_MAX);
368 }
369 
370 static OUString ReplaceOneChar(const OUString& oldOUString, const OUString& replacedChar, const OUString& replaceStr)
371 {
372  int iReplace = oldOUString.lastIndexOf(replacedChar);
373  OUString aRet = oldOUString;
374  while(iReplace > -1)
375  {
376  aRet = aRet.replaceAt(iReplace,1, replaceStr);
377  iReplace = aRet.lastIndexOf(replacedChar,iReplace);
378  }
379  return aRet;
380 }
381 
382 static OUString ReplaceFourChar(const OUString& oldOUString)
383 {
384  OUString aRet = ReplaceOneChar(oldOUString,"\\","\\\\");
385  aRet = ReplaceOneChar(aRet,";","\\;");
386  aRet = ReplaceOneChar(aRet,"=","\\=");
387  aRet = ReplaceOneChar(aRet,",","\\,");
388  aRet = ReplaceOneChar(aRet,":","\\:");
389  return aRet;
390 }
391 
393 {
394  SolarMutexGuard g;
395 
396  css::uno::Any strRet;
397  SwFrameFormat *pFrameFormat = GetTableBoxFormat();
398  assert(pFrameFormat);
399 
400  const SwTableBoxFormula& tbl_formula = pFrameFormat->GetTableBoxFormula();
401 
402  OUString strFormula = ReplaceFourChar(tbl_formula.GetFormula());
403  OUString strFor("Formula:");
404  strFor += strFormula;
405  strFor += ";" ;
406  strRet <<= strFor;
407 
408  return strRet;
409 }
410 
412 {
413  SolarMutexGuard g;
414 
415  const SvxBrushItem &rBack = GetFrame()->GetAttrSet()->GetBackground();
416  Color crBack = rBack.GetColor();
417 
418  if (COL_AUTO == crBack)
419  {
420  uno::Reference<XAccessible> xAccDoc = getAccessibleParent();
421  if (xAccDoc.is())
422  {
423  uno::Reference<XAccessibleComponent> xComponentDoc(xAccDoc, uno::UNO_QUERY);
424  if (xComponentDoc.is())
425  {
426  crBack = Color(xComponentDoc->getBackground());
427  }
428  }
429  }
430  return sal_Int32(crBack);
431 }
432 
433 // XAccessibleSelection
435  sal_Int32 nChildIndex )
436 {
438 }
439 
441  sal_Int32 nChildIndex )
442 {
443  return m_aSelectionHelper.isAccessibleChildSelected(nChildIndex);
444 }
445 
447 {
448 }
449 
451 {
453 }
454 
456 {
458 }
459 
461  sal_Int32 nSelectedChildIndex )
462 {
463  return m_aSelectionHelper.getSelectedAccessibleChild(nSelectedChildIndex);
464 }
465 
467  sal_Int32 nSelectedChildIndex )
468 {
469  m_aSelectionHelper.deselectAccessibleChild(nSelectedChildIndex);
470 }
471 
472 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Reference< css::accessibility::XAccessible > getAccessibleParentImpl()
Definition: acccontext.cxx:622
Base class of the Writer layout elements.
Definition: frame.hxx:295
static OUString ReplaceOneChar(const OUString &oldOUString, const OUString &replacedChar, const OUString &replaceStr)
Definition: acccell.cxx:370
virtual void Dispose(bool bRecursive, bool bCanSkipInvisible=true) override
Definition: acccell.cxx:260
const SvxBrushItem & GetBackground(bool=true) const
Definition: frmatr.hxx:58
virtual bool HasCursor() override
Definition: acccell.cxx:226
std::string GetValue
const sal_Char sAccessibleServiceName[]
Definition: acccontext.hxx:43
virtual sal_Int32 SAL_CALL getSelectedAccessibleChildCount() override
Definition: acccell.cxx:455
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:30
SwViewShell * GetShell()
convenience method to get the SwViewShell through accessibility map
Definition: acccontext.hxx:116
const_iterator find(const Value &x) const
virtual void SAL_CALL deselectAccessibleChild(sal_Int32 nSelectedChildIndex) override
Definition: acccell.cxx:466
virtual void SAL_CALL clearAccessibleSelection() override
Definition: acccell.cxx:446
virtual css::uno::Any SAL_CALL getMaximumValue() override
Definition: acccell.cxx:360
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: acccell.cxx:311
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
bool IsInPagePreview() const
Definition: accframe.hxx:87
constexpr::Color COL_AUTO(0xFF, 0xFF, 0xFF, 0xFF)
bool IsSelected()
Definition: acccell.cxx:56
static sw::access::SwAccessibleChild GetChild(SwAccessibleMap &rAccMap, const SwRect &rVisArea, const SwFrame &rFrame, sal_Int32 &rPos, bool bInPagePreview)
Definition: accframe.cxx:77
const SwTableBox * GetTabBox() const
Definition: cellfrm.hxx:52
const SwFrame * GetFrame() const
Definition: accframe.hxx:103
bool isAccessibleChildSelected(sal_Int32 nChildIndex)
virtual void InvalidatePosOrSize(const SwRect &rFrame) override
Definition: acccell.cxx:270
char sal_Char
virtual void SAL_CALL selectAccessibleChild(sal_Int32 nChildIndex) override
Definition: acccell.cxx:434
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
Definition: acccell.cxx:318
const SwAttrSet * GetAttrSet() const
WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for SwTextFrame, use GetBreakItem()/GetPageDescItem() instead.
Definition: findfrm.cxx:674
css::uno::Reference< css::accessibility::XAccessible > getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)
const Color & GetColor() const
void FireStateChangedEvent(sal_Int16 nState, bool bNewState)
Definition: acccontext.cxx:467
const SwFrame * GetSwFrame() const
Definition: accfrmobj.hxx:58
OUString GetName() const
Definition: swtable.cxx:1828
virtual css::uno::Any SAL_CALL getCurrentValue() override
Definition: acccell.cxx:335
Style of a layout element.
Definition: frmfmt.hxx:57
SwTabFrame * FindMaster(bool bFirstMaster=false) const
Definition: flowfrm.cxx:714
virtual sal_Bool SAL_CALL setCurrentValue(const css::uno::Any &aNumber) override
Definition: acccell.cxx:344
const_iterator begin() const
const OUString & GetName() const
Definition: acccontext.hxx:333
rtl::Reference< SwAccessibleTable > m_pAccTable
Definition: acccell.hxx:45
SwFrameFormat * GetTableBoxFormat() const
Definition: acccell.cxx:325
SwAccessibleCell(std::shared_ptr< SwAccessibleMap > const &pInitMap, const SwCellFrame *pCellFrame)
Definition: acccell.cxx:101
const sal_Char sImplementationName[]
Definition: acccell.cxx:54
virtual OUString SAL_CALL getImplementationName() override
Definition: acccell.cxx:241
unsigned char sal_Bool
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent() override
Definition: acccontext.cxx:644
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:425
virtual void InvalidateCursorPos_() override
Definition: acccell.cxx:191
virtual void InvalidatePosOrSize(const SwRect &rFrame)
const_iterator end() const
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex) override
Definition: acccell.cxx:460
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:460
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: acccell.cxx:251
virtual void GetStates(::utl::AccessibleStateSetHelper &rStateSet) override
Definition: acccell.cxx:79
const OUString & GetFormula() const
Definition: cellfml.hxx:135
virtual sal_Bool SAL_CALL isAccessibleChildSelected(sal_Int32 nChildIndex) override
Definition: acccell.cxx:440
bool IsTabFrame() const
Definition: frame.hxx:1194
#define SAL_WARN_IF(condition, area, stream)
bool m_bIsSelected
Definition: acccell.hxx:38
virtual void Dispose(bool bRecursive, bool bCanSkipInvisible=true)
virtual css::uno::Any SAL_CALL getMinimumValue() override
Definition: acccell.cxx:365
virtual void GetStates(::utl::AccessibleStateSetHelper &rStateSet)
Definition: acccontext.cxx:481
bool IsAccessible(bool bPagePreview) const
Definition: accfrmobj.cxx:124
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &aType) override
Definition: acccell.cxx:282
void selectAccessibleChild(sal_Int32 nChildIndex)
sal_Int32 SAL_CALL getBackground() override
Definition: acccell.cxx:411
const SwFrame * GetParent() const
Definition: accframe.hxx:155
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:386
static OUString ReplaceFourChar(const OUString &oldOUString)
Definition: acccell.cxx:382
bool InvalidateMyCursorPos()
Definition: acccell.cxx:123
css::uno::Any SAL_CALL getExtendedAttributes() override
Definition: acccell.cxx:392
virtual ~SwAccessibleCell() override
Definition: acccell.cxx:232
css::uno::Sequence< css::uno::Type > SAL_CALL getTypes()
SwAccessibleMap * GetMap()
Definition: acccontext.hxx:112
virtual OUString SAL_CALL getAccessibleDescription() override
Return this object's description.
Definition: acccell.cxx:236
void deselectAccessibleChild(sal_Int32 nChildIndex)
virtual void SAL_CALL selectAllAccessibleChildren() override
Definition: acccell.cxx:450
mutable::osl::Mutex m_Mutex
Definition: acccontext.hxx:64
void SetCursorContext(const ::rtl::Reference< SwAccessibleContext > &rCursorContext)
Definition: accmap.cxx:2740
virtual sal_Bool SAL_CALL supportsService(const OUString &sServiceName) override
Return whether the specified service is supported by this class.
Definition: acccell.cxx:246
const SwRect & GetVisArea() const
Definition: accframe.hxx:136
bool InvalidateChildrenCursorPos(const SwFrame *pFrame)
Definition: acccell.cxx:152
SwAccessibleSelectionHelper m_aSelectionHelper
Definition: acccell.hxx:37
void AddState(sal_Int16 aState)
void SetName(const OUString &rName)
Definition: acccontext.hxx:99
SwCellFrame is one table cell in the document layout.
Definition: cellfrm.hxx:30
const SwTableBoxFormula & GetTableBoxFormula(bool=true) const
Definition: cellatr.hxx:107