LibreOffice Module sw (master)  1
accnotextframe.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 <vcl/svapp.hxx>
21 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
22 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
25 #include <frmfmt.hxx>
26 #include <ndnotxt.hxx>
27 #include <flyfrm.hxx>
28 #include <cntfrm.hxx>
29 #include <notxtfrm.hxx>
30 #include <hints.hxx>
31 #include "accnotextframe.hxx"
32 #include <fmturl.hxx>
33 #include "accnotexthyperlink.hxx"
34 #include <vcl/imap.hxx>
36 #include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
37 #include <doc.hxx>
38 
39 using namespace ::com::sun::star;
40 using namespace ::com::sun::star::accessibility;
42 
44 {
45  const SwNoTextNode *pNd = nullptr;
46  const SwFlyFrame *pFlyFrame = static_cast< const SwFlyFrame *>( GetFrame() );
47  if( pFlyFrame->Lower() && pFlyFrame->Lower()->IsNoTextFrame() )
48  {
49  const SwNoTextFrame *pContentFrame =
50  static_cast<const SwNoTextFrame *>(pFlyFrame->Lower());
51  const SwContentNode* pSwContentNode = pContentFrame->GetNode();
52  if(pSwContentNode != nullptr)
53  {
54  pNd = pSwContentNode->GetNoTextNode();
55  }
56  }
57 
58  return pNd;
59 }
60 
62  std::shared_ptr<SwAccessibleMap> const& pInitMap,
63  sal_Int16 nInitRole,
64  const SwFlyFrame* pFlyFrame ) :
65  SwAccessibleFrameBase( pInitMap, nInitRole, pFlyFrame ),
66  m_aListener(*this),
67  msTitle(),
68  msDesc()
69 {
70  const SwNoTextNode* pNd = GetNoTextNode();
71  m_aListener.StartListening(const_cast<SwNoTextNode*>(pNd));
72  // #i73249#
73  // consider new attributes Title and Description
74  if( pNd )
75  {
76  msTitle = pNd->GetTitle();
77 
78  msDesc = pNd->GetDescription();
79  if ( msDesc.isEmpty() &&
80  msTitle != GetName() )
81  {
82  msDesc = msTitle;
83  }
84  }
85 }
86 
88 {
89 }
90 
92 {
93  const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0 ;
94  // #i73249#
95  // suppress handling of RES_NAME_CHANGED in case that attribute Title is
96  // used as the accessible name.
97  if ( nWhich != RES_NAME_CHANGED ||
98  msTitle.isEmpty() )
99  {
100  SwAccessibleFrameBase::Modify( pOld, pNew );
101  if (!GetRegisteredIn())
102  return; // probably was deleted - avoid doing anything
103  }
104 
105  if (nWhich != RES_TITLE_CHANGED && nWhich != RES_DESCRIPTION_CHANGED)
106  return;
107 
108  const SwNoTextNode *pNd = GetNoTextNode();
109  assert( m_aListener.IsListeningTo(pNd) && "invalid frame" );
110  switch( nWhich )
111  {
112  // #i73249#
113  case RES_TITLE_CHANGED:
114  {
115  OUString sOldTitle, sNewTitle;
116  const SwStringMsgPoolItem* pOldItem = dynamic_cast<const SwStringMsgPoolItem*>(pOld);
117  if (pOldItem)
118  sOldTitle = pOldItem->GetString();
119  const SwStringMsgPoolItem* pNewItem = dynamic_cast<const SwStringMsgPoolItem*>(pNew);
120  if (pNewItem)
121  sNewTitle = pNewItem->GetString();
122  if ( sOldTitle == sNewTitle )
123  {
124  break;
125  }
126  msTitle = sNewTitle;
127  AccessibleEventObject aEvent;
128  aEvent.EventId = AccessibleEventId::NAME_CHANGED;
129  aEvent.OldValue <<= sOldTitle;
130  aEvent.NewValue <<= msTitle;
131  FireAccessibleEvent( aEvent );
132 
133  if ( !pNd->GetDescription().isEmpty() )
134  {
135  break;
136  }
137  [[fallthrough]];
138  }
140  {
141  if ( pNd && GetFrame() )
142  {
143  const OUString sOldDesc( msDesc );
144 
145  const OUString& rDesc = pNd->GetDescription();
146  msDesc = rDesc;
147  if ( msDesc.isEmpty() &&
148  msTitle != GetName() )
149  {
150  msDesc = msTitle;
151  }
152 
153  if ( msDesc != sOldDesc )
154  {
155  AccessibleEventObject aEvent;
156  aEvent.EventId = AccessibleEventId::DESCRIPTION_CHANGED;
157  aEvent.OldValue <<= sOldDesc;
158  aEvent.NewValue <<= msDesc;
159  FireAccessibleEvent( aEvent );
160  }
161  }
162  }
163  break;
164  }
165 }
166 
167 void SwAccessibleNoTextFrame::Dispose(bool bRecursive, bool bCanSkipInvisible)
168 {
169  SolarMutexGuard aGuard;
171  SwAccessibleFrameBase::Dispose(bRecursive, bCanSkipInvisible);
172 }
173 
174 // #i73249#
176 {
177  SolarMutexGuard aGuard;
178 
179  ThrowIfDisposed();
180 
181  if ( !msTitle.isEmpty() )
182  {
183  return msTitle;
184  }
185 
187 }
188 
190 {
191  SolarMutexGuard aGuard;
192 
193  ThrowIfDisposed();
194 
195  return msDesc;
196 }
197 
198 // XInterface
199 
201 {
202  if( aType ==
204  {
205  uno::Reference<XAccessibleImage> xImage = this;
206  return uno::Any(xImage);
207  }
208  else if ( aType == cppu::UnoType<XAccessibleHypertext>::get())
209  {
210  uno::Reference<XAccessibleHypertext> aAccHypertext = this;
211  return uno::Any( aAccHypertext );
212  }
213  else
214  return SwAccessibleContext::queryInterface( aType );
215 }
216 
217 // XTypeProvider
218 
219 uno::Sequence< uno::Type > SAL_CALL SwAccessibleNoTextFrame::getTypes()
220 {
221  return cppu::OTypeCollection(
223  SwAccessibleFrameBase::getTypes() ).getTypes();
224 }
225 
227 
232 {
233  return getAccessibleDescription();
234 }
235 
237 {
238  return getSize().Height;
239 }
240 
242 {
243  return getSize().Width;
244 }
245 
246 // XAccessibleText
247 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getCaretPosition( ){return 0;}
248 sal_Bool SAL_CALL SwAccessibleNoTextFrame::setCaretPosition( sal_Int32 ){return false;}
249 sal_Unicode SAL_CALL SwAccessibleNoTextFrame::getCharacter( sal_Int32 ){return 0;}
250 css::uno::Sequence< css::beans::PropertyValue > SAL_CALL SwAccessibleNoTextFrame::getCharacterAttributes( sal_Int32 , const css::uno::Sequence< OUString >& )
251 {
252  return uno::Sequence<beans::PropertyValue>();
253 }
254 css::awt::Rectangle SAL_CALL SwAccessibleNoTextFrame::getCharacterBounds( sal_Int32 )
255 {
256  return css::awt::Rectangle(0, 0, 0, 0 );
257 }
258 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getCharacterCount( ){return 0;}
259 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getIndexAtPoint( const css::awt::Point& ){return 0;}
260 OUString SAL_CALL SwAccessibleNoTextFrame::getSelectedText( ){return OUString();}
261 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getSelectionStart( ){return 0;}
262 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getSelectionEnd( ){return 0;}
263 sal_Bool SAL_CALL SwAccessibleNoTextFrame::setSelection( sal_Int32 , sal_Int32 ){return true;}
264 OUString SAL_CALL SwAccessibleNoTextFrame::getText( ){return OUString();}
265 OUString SAL_CALL SwAccessibleNoTextFrame::getTextRange( sal_Int32 , sal_Int32 ){return OUString();}
266 css::accessibility::TextSegment SAL_CALL SwAccessibleNoTextFrame::getTextAtIndex( sal_Int32 , sal_Int16 )
267 {
268  css::accessibility::TextSegment aResult;
269  return aResult;
270 }
271 css::accessibility::TextSegment SAL_CALL SwAccessibleNoTextFrame::getTextBeforeIndex( sal_Int32, sal_Int16 )
272 {
273  css::accessibility::TextSegment aResult;
274  return aResult;
275 }
276 css::accessibility::TextSegment SAL_CALL SwAccessibleNoTextFrame::getTextBehindIndex( sal_Int32 , sal_Int16 )
277 {
278  css::accessibility::TextSegment aResult;
279  return aResult;
280 }
281 
282 sal_Bool SAL_CALL SwAccessibleNoTextFrame::copyText( sal_Int32, sal_Int32 ){return true;}
283 
284 // XAccessibleHyperText
285 
287 {
288  SolarMutexGuard aGuard;
289 
290  ThrowIfDisposed();
291 
292  sal_Int32 nCount = 0;
293  SwFormatURL aURL( static_cast<const SwLayoutFrame*>(GetFrame())->GetFormat()->GetURL() );
294 
295  if(aURL.GetMap() || !aURL.GetURL().isEmpty())
296  nCount = 1;
297 
298  return nCount;
299 }
300 
301 uno::Reference< XAccessibleHyperlink > SAL_CALL
303 {
304  SolarMutexGuard aGuard;
305 
306  ThrowIfDisposed();
307 
308  SwFormatURL aURL( static_cast<const SwLayoutFrame*>(GetFrame())->GetFormat()->GetURL() );
309 
310  if( nLinkIndex > 0 )
311  throw lang::IndexOutOfBoundsException();
312 
313  if( aURL.GetMap() || !aURL.GetURL().isEmpty() )
314  {
315  if ( !m_xHyperlink.is() )
316  {
318  }
319 
320  return m_xHyperlink;
321  }
322 
323  return nullptr;
324 }
325 
326 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getHyperLinkIndex( sal_Int32 )
327 {
328  return 0;
329 }
330 
331 uno::Reference<XAccessibleRelationSet> SAL_CALL SwAccessibleNoTextFrame::getAccessibleRelationSet( )
332 {
333  return new AccessibleRelationSetHelper();
334 }
335 
336 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual sal_Int32 SAL_CALL getAccessibleImageHeight() override
virtual css::awt::Size SAL_CALL getSize() override
Definition: acccontext.cxx:913
void FireAccessibleEvent(css::accessibility::AccessibleEventObject &rEvent)
Definition: acccontext.cxx:443
virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew) override
virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex(sal_Int32 nIndex, sal_Int16 aTextType) override
virtual sal_Bool SAL_CALL copyText(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override
virtual OUString SAL_CALL getTextRange(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override
virtual OUString SAL_CALL getAccessibleImageDescription() override
XAccessibleImage.
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &aType) override
virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew) override
virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex(sal_Int32 nIndex, sal_Int16 aTextType) override
virtual css::awt::Rectangle SAL_CALL getCharacterBounds(sal_Int32 nIndex) override
virtual OUString SAL_CALL getText() override
virtual css::uno::Reference< css::accessibility::XAccessibleHyperlink > SAL_CALL getHyperLink(sal_Int32 nLinkIndex) override
sal_uInt16 sal_Unicode
virtual ~SwAccessibleNoTextFrame() override
virtual sal_Bool SAL_CALL setCaretPosition(sal_Int32 nIndex) override
virtual sal_Int32 SAL_CALL getHyperLinkIndex(sal_Int32 nCharIndex) override
const SwFrame * GetFrame() const
Definition: accframe.hxx:103
virtual sal_Bool SAL_CALL setSelection(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override
const OUString & GetString() const
Definition: hints.hxx:293
virtual sal_Int32 SAL_CALL getSelectionEnd() override
virtual sal_Int32 SAL_CALL getIndexAtPoint(const css::awt::Point &aPoint) override
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes(sal_Int32 nIndex, const css::uno::Sequence< OUString > &aRequestedAttributes) override
#define RES_TITLE_CHANGED
Definition: hintids.hxx:311
virtual OUString SAL_CALL getAccessibleName() override
const OUString & GetName() const
Definition: acccontext.hxx:333
bool IsListeningTo(const SwModify *const pDepend) const
Definition: calbck.cxx:342
virtual sal_Int32 SAL_CALL getCharacterCount() override
const SwFrame * Lower() const
Definition: layfrm.hxx:100
SwNoTextNode * GetNoTextNode()
Definition: ndnotxt.hxx:96
SwAccessibleNoTextFrame(std::shared_ptr< SwAccessibleMap > const &pInitMap, sal_Int16 nInitRole, const SwFlyFrame *pFlyFrame)
unsigned char sal_Bool
virtual OUString SAL_CALL getSelectedText() override
friend class SwAccessibleNoTextHyperlink
virtual sal_Unicode SAL_CALL getCharacter(sal_Int32 nIndex) override
OUString GetDescription() const
Definition: ndnotxt.cxx:284
const SwNoTextNode * GetNoTextNode() const
virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet() override
#define RES_DESCRIPTION_CHANGED
Definition: hintids.hxx:312
sw::WriterMultiListener m_aListener
virtual sal_Int32 SAL_CALL getAccessibleImageWidth() override
const ImageMap * GetMap() const
Definition: fmturl.hxx:68
void StartListening(SwModify *pDepend)
Definition: calbck.cxx:335
const SwContentNode * GetNode() const
Definition: notxtfrm.hxx:60
virtual OUString SAL_CALL getAccessibleName() override
Definition: acccontext.cxx:680
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
general base class for all free-flowing frames
Definition: flyfrm.hxx:60
OUString GetTitle() const
Definition: ndnotxt.cxx:260
bool IsNoTextFrame() const
Definition: frame.hxx:1214
const SwModify * GetRegisteredIn() const
Definition: calbck.hxx:157
#define RES_NAME_CHANGED
Definition: hintids.hxx:310
virtual OUString SAL_CALL getAccessibleDescription() override
Return this object's description.
css::uno::Sequence< css::uno::Type > SAL_CALL getTypes()
css::uno::Reference< css::accessibility::XAccessibleHyperlink > m_xHyperlink
virtual sal_Int32 SAL_CALL getSelectionStart() override
virtual void Dispose(bool bRecursive, bool bCanSkipInvisible=true) override
virtual sal_Int32 SAL_CALL getCaretPosition() override
virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex(sal_Int32 nIndex, sal_Int16 aTextType) override
sal_uInt16 Which() const
virtual sal_Int32 SAL_CALL getHyperLinkCount() override
virtual void Dispose(bool bRecursive, bool bCanSkipInvisible=true) override
const OUString & GetURL() const
Definition: fmturl.hxx:66