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