LibreOffice Module sw (master)  1
accfrmobj.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 "accfrmobj.hxx"
21 
22 #include <accmap.hxx>
23 #include "acccontext.hxx"
24 
25 #include <viewsh.hxx>
26 #include <rootfrm.hxx>
27 #include <flyfrm.hxx>
28 #include <pagefrm.hxx>
29 #include <cellfrm.hxx>
30 #include <swtable.hxx>
31 #include <dflyobj.hxx>
32 #include <frmfmt.hxx>
33 #include <fmtanchr.hxx>
34 #include <dcontact.hxx>
35 
36 #include <vcl/window.hxx>
37 
38 namespace sw::access {
39 
41  : mpFrame( nullptr )
42  , mpDrawObj( nullptr )
43  , mpWindow( nullptr )
44 {}
45 
47  : mpFrame( nullptr )
48  , mpDrawObj( nullptr )
49  , mpWindow( nullptr )
50 {
51  Init( pDrawObj );
52 }
53 
55  : mpFrame( nullptr )
56  , mpDrawObj( nullptr )
57  , mpWindow( nullptr )
58 {
59  Init( pFrame );
60 }
61 
63  : mpFrame( nullptr )
64  , mpDrawObj( nullptr )
65  , mpWindow( nullptr )
66 {
67  Init( pWindow );
68 }
69 
71  const SdrObject* pDrawObj,
72  vcl::Window* pWindow )
73  : mpFrame( nullptr )
74  , mpDrawObj( nullptr )
75  , mpWindow( nullptr )
76 {
77  if ( pFrame )
78  {
79  Init( pFrame );
80  }
81  else if ( pDrawObj )
82  {
83  Init( pDrawObj );
84  }
85  else if ( pWindow )
86  {
87  Init( pWindow );
88  }
89  OSL_ENSURE( (!pFrame || pFrame == mpFrame) &&
90  (!pDrawObj || pDrawObj == mpDrawObj) &&
91  (!pWindow || pWindow == mpWindow),
92  "invalid frame/object/window combination" );
93 
94 }
95 
97 
98 void SwAccessibleChild::Init( const SdrObject* pDrawObj )
99 {
100  mpDrawObj = pDrawObj;
101  const SwVirtFlyDrawObj* pFlyDrawObj = dynamic_cast<const SwVirtFlyDrawObj*>(mpDrawObj);
102  mpFrame = pFlyDrawObj ? pFlyDrawObj->GetFlyFrame() : nullptr;
103  mpWindow = nullptr;
104 }
105 
106 void SwAccessibleChild::Init( const SwFrame* pFrame )
107 {
108  mpFrame = pFrame;
110  ? static_cast < const SwFlyFrame * >( mpFrame )->GetVirtDrawObj()
111  : nullptr;
112  mpWindow = nullptr;
113 }
114 
116 {
117  mpWindow = pWindow;
118  mpFrame = nullptr;
119  mpDrawObj = nullptr;
120 }
121 
122 bool SwAccessibleChild::IsAccessible( bool bPagePreview ) const
123 {
124  bool bRet( false );
125 
126  if ( mpFrame )
127  {
128  bRet = mpFrame->IsAccessibleFrame() &&
129  ( !mpFrame->IsCellFrame() ||
130  static_cast<const SwCellFrame *>( mpFrame )->GetTabBox()->GetSttNd() != nullptr ) &&
131  !mpFrame->IsInCoveredCell() &&
132  ( bPagePreview ||
133  !mpFrame->IsPageFrame() );
134  }
135  else if ( mpDrawObj )
136  {
137  bRet = true;
138  }
139  else if ( mpWindow )
140  {
141  bRet = true;
142  }
143 
144  return bRet;
145 }
146 
148 {
149  bool bRet( false );
150 
151  if ( mpFrame )
152  {
153  bRet = mpFrame->IsFlyFrame() &&
154  static_cast< const SwFlyFrame *>(mpFrame)->IsFlyInContentFrame();
155  }
156  else if ( mpDrawObj )
157  {
158  const SwFrameFormat* pFrameFormat = ::FindFrameFormat( mpDrawObj );
159  bRet = pFrameFormat
160  && (RndStdIds::FLY_AS_CHAR == pFrameFormat->GetAnchor().GetAnchorId());
161  }
162  else if ( mpWindow )
163  {
164  bRet = false;
165  }
166 
167  return bRet;
168 }
169 
171 {
172  Init( pDrawObj );
173  return *this;
174 }
175 
177 {
178  Init( pFrame );
179  return *this;
180 }
181 
183 {
184  Init( pWindow );
185  return *this;
186 }
187 
189 {
190  return mpFrame == r.mpFrame &&
191  mpDrawObj == r.mpDrawObj &&
192  mpWindow == r.mpWindow;
193 }
194 
196 {
197  return mpFrame != nullptr ||
198  mpDrawObj != nullptr ||
199  mpWindow != nullptr;
200 }
201 
203 {
204  bool bRet( false );
205 
206  if ( !mpFrame )
207  {
208  bRet = true;
209  }
210  else
211  {
212  bRet = mpFrame->IsRootFrame() ||
213  !( mpFrame->IsTabFrame() ||
214  mpFrame->IsInTab() ||
215  ( IsBoundAsChar() &&
216  static_cast<const SwFlyFrame*>(mpFrame)->GetAnchorFrame()->IsInTab() ) );
217  }
218 
219  return bRet;
220 }
221 
223 {
224  SwRect aBox;
225 
226  if ( mpFrame )
227  {
228  if ( mpFrame->IsPageFrame() &&
229  static_cast< const SwPageFrame * >( mpFrame )->IsEmptyPage() )
230  {
231  aBox = SwRect( mpFrame->getFrameArea().Left(), mpFrame->getFrameArea().Top()-1, 1, 1 );
232  }
233  else if ( mpFrame->IsTabFrame() )
234  {
235  aBox = mpFrame->getFrameArea();
237  }
238  else
239  {
240  aBox = mpFrame->getFrameArea();
241  }
242  }
243  else if( mpDrawObj )
244  {
245  const SwContact* const pContact = ::GetUserCall(mpDrawObj);
246  // assume that a) the SwVirt* objects that don't have this are handled
247  // by the mpFrame case above b) for genuine SdrObject this must be set
248  // if it's connected to layout
249  assert(dynamic_cast<SwDrawContact const*>(pContact));
250  SwPageFrame const*const pPage(const_cast<SwAnchoredObject *>(
251  pContact->GetAnchoredObj(mpDrawObj))->FindPageFrameOfAnchor());
252  if (pPage) // may end up here with partial layout -> not visible
253  {
254  aBox = SwRect( mpDrawObj->GetCurrentBoundRect() );
255  // tdf#91260 drawing object may be partially off-page
256  aBox.Intersection(pPage->getFrameArea());
257  }
258  }
259  else if ( mpWindow )
260  {
261  vcl::Window *pWin = rAccMap.GetShell()->GetWin();
262  if (pWin)
263  {
264  aBox = SwRect( pWin->PixelToLogic(
266  mpWindow->GetSizePixel() ) ) );
267  }
268  }
269 
270  return aBox;
271 }
272 
274 {
275  SwRect aBound;
276 
277  if( mpFrame )
278  {
279  if( mpFrame->IsPageFrame() &&
280  static_cast< const SwPageFrame * >( mpFrame )->IsEmptyPage() )
281  {
282  aBound = SwRect( mpFrame->getFrameArea().Left(), mpFrame->getFrameArea().Top()-1, 0, 0 );
283  }
284  else
285  aBound = mpFrame->GetPaintArea();
286  }
287  else if( mpDrawObj )
288  {
289  aBound = GetBox( rAccMap );
290  }
291  else if ( mpWindow )
292  {
293  aBound = GetBox( rAccMap );
294  }
295 
296  return aBound;
297 }
298 
300 {
301  bool bAlwaysIncludedAsChild( false );
302 
303  if ( mpWindow )
304  {
305  bAlwaysIncludedAsChild = true;
306  }
307 
308  return bAlwaysIncludedAsChild;
309 }
310 
311 const SwFrame* SwAccessibleChild::GetParent( const bool bInPagePreview ) const
312 {
313  const SwFrame* pParent( nullptr );
314 
315  if ( mpFrame )
316  {
317  if( mpFrame->IsFlyFrame() )
318  {
319  const SwFlyFrame* pFly = static_cast< const SwFlyFrame *>( mpFrame );
320  if( pFly->IsFlyInContentFrame() )
321  {
322  // For RndStdIds::FLY_AS_CHAR the parent is the anchor
323  pParent = pFly->GetAnchorFrame();
324  OSL_ENSURE( SwAccessibleChild( pParent ).IsAccessible( bInPagePreview ),
325  "parent is not accessible" );
326  }
327  else
328  {
329  // In any other case the parent is the root frm
330  // (in page preview, the page frame)
331  if( bInPagePreview )
332  pParent = pFly->FindPageFrame();
333  else
334  pParent = pFly->getRootFrame();
335  }
336  }
337  else
338  {
339  SwAccessibleChild aUpper( mpFrame->GetUpper() );
340  while( aUpper.GetSwFrame() && !aUpper.IsAccessible(bInPagePreview) )
341  {
342  aUpper = aUpper.GetSwFrame()->GetUpper();
343  }
344  pParent = aUpper.GetSwFrame();
345  }
346  }
347  else if( mpDrawObj )
348  {
349  const SwDrawContact *pContact =
350  static_cast< const SwDrawContact* >( GetUserCall( mpDrawObj ) );
351  OSL_ENSURE( pContact, "sdr contact is missing" );
352  if( pContact )
353  {
354  const SwFrameFormat *pFrameFormat = pContact->GetFormat();
355  OSL_ENSURE( pFrameFormat, "frame format is missing" );
356  if( pFrameFormat && RndStdIds::FLY_AS_CHAR == pFrameFormat->GetAnchor().GetAnchorId() )
357  {
358  // For RndStdIds::FLY_AS_CHAR the parent is the anchor
359  pParent = pContact->GetAnchorFrame();
360  OSL_ENSURE( SwAccessibleChild( pParent ).IsAccessible( bInPagePreview ),
361  "parent is not accessible" );
362 
363  }
364  else
365  {
366  // In any other case the parent is the root frm
367  SwFrame const*const pAnchor(pContact->GetAnchorFrame());
368  if (pAnchor) // null if object removed from layout
369  {
370  if (bInPagePreview)
371  pParent = pAnchor->FindPageFrame();
372  else
373  pParent = pAnchor->getRootFrame();
374  }
375  }
376  }
377  }
378  else if ( mpWindow )
379  {
380  css::uno::Reference < css::accessibility::XAccessible > xAcc =
382  if ( xAcc.is() )
383  {
384  css::uno::Reference < css::accessibility::XAccessibleContext > xAccContext =
385  xAcc->getAccessibleContext();
386  if ( xAccContext.is() )
387  {
388  css::uno::Reference < css::accessibility::XAccessible > xAccParent =
389  xAccContext->getAccessibleParent();
390  if ( xAccParent.is() )
391  {
392  SwAccessibleContext* pAccParentImpl =
393  dynamic_cast< SwAccessibleContext *>( xAccParent.get() );
394  if ( pAccParentImpl )
395  {
396  pParent = pAccParentImpl->GetFrame();
397  }
398  }
399  }
400  }
401  }
402 
403  return pParent;
404 }
405 
406 } // eof of namespace sw::access
407 
408 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual Point GetPosPixel() const
Base class for the following contact objects (frame + draw objects).
Definition: dcontact.hxx:66
Base class of the Writer layout elements.
Definition: frame.hxx:295
SwAccessibleChild & operator=(SwAccessibleChild const &)=default
const SdrObject * mpDrawObj
Definition: accfrmobj.hxx:77
virtual const tools::Rectangle & GetCurrentBoundRect() const
bool IsRootFrame() const
Definition: frame.hxx:1150
VclPtr< vcl::Window > mpWindow
Definition: accfrmobj.hxx:78
SwRect GetBounds(const SwAccessibleMap &rAccMap) const
Definition: accfrmobj.cxx:273
virtual Size GetSizePixel() const
bool IsCellFrame() const
Definition: frame.hxx:1202
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
SwContact * GetUserCall(const SdrObject *pObj)
Returns the UserCall if applicable from the group object.
Definition: dcontact.cxx:176
bool IsInCoveredCell() const
Definition: tabfrm.cxx:5707
SwRect GetPaintArea() const
|* The paintarea is the area, in which the content of a frame is allowed |* to be displayed...
Definition: ssfrm.cxx:581
bool IsFlyFrame() const
Definition: frame.hxx:1186
SwViewShell * GetShell() const
Definition: accmap.hxx:169
void Top(const long nTop)
Definition: swrect.hxx:202
const SwFrame * GetAnchorFrame(const SdrObject *_pDrawObj=nullptr) const
Definition: dcontact.cxx:787
const SwFrame * GetFrame() const
Definition: accframe.hxx:103
const SwRect & getFrameArea() const
Definition: frame.hxx:175
css::uno::Reference< css::accessibility::XAccessible > GetAccessible(bool bCreate=true)
bool IsInTab() const
Definition: frame.hxx:931
SwRect & Intersection(const SwRect &rRect)
Definition: swrect.cxx:54
bool operator==(const SwAccessibleChild &r) const
Definition: accfrmobj.cxx:188
SwFrameFormat * FindFrameFormat(SdrObject *pObj)
The Get reverse way: seeks the format to the specified object.
Definition: dcontact.cxx:125
bool IsVisibleChildrenOnly() const
Definition: accfrmobj.cxx:202
bool IsFlyInContentFrame() const
Definition: flyfrm.hxx:193
const SwFrame * GetSwFrame() const
Definition: accfrmobj.hxx:58
VclPtr< vcl::Window > mpWindow
Style of a layout element.
Definition: frmfmt.hxx:57
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
SwFrameFormat * GetFormat()
Definition: dcontact.hxx:112
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
void Init(const SdrObject *pDrawObj)
Definition: accfrmobj.cxx:98
const SwFrame * GetParent(const bool bInPagePreview) const
Definition: accfrmobj.cxx:311
SwPageFrame * FindPageFrame()
Definition: frame.hxx:658
SwLayoutFrame * GetUpper()
Definition: frame.hxx:656
bool AlwaysIncludeAsChild() const
indicating, if accessible child is included even, if the corresponding object is not visible...
Definition: accfrmobj.cxx:299
virtual const SwAnchoredObject * GetAnchoredObj(const SdrObject *_pSdrObj) const =0
A page of the document layout.
Definition: pagefrm.hxx:40
Point PixelToLogic(const Point &rDevicePt) const
void Left(const long nLeft)
Definition: swrect.hxx:193
SwFlyFrame * GetFlyFrame()
Definition: dflyobj.hxx:127
bool IsTabFrame() const
Definition: frame.hxx:1194
general base class for all free-flowing frames
Definition: flyfrm.hxx:60
vcl::Window * GetWin() const
Definition: viewsh.hxx:340
bool IsAccessible(bool bPagePreview) const
Definition: accfrmobj.cxx:122
bool IsPageFrame() const
Definition: frame.hxx:1154
bool IsAccessibleFrame() const
Definition: frame.hxx:1226
SwRect GetBox(const SwAccessibleMap &rAccMap) const
Definition: accfrmobj.cxx:222
const SwFrame * GetAnchorFrame() const
SwRootFrame * getRootFrame()
Definition: frame.hxx:657
SwCellFrame is one table cell in the document layout.
Definition: cellfrm.hxx:30