LibreOffice Module sw (master)  1
accframe.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 <hintids.hxx>
21 #include <editeng/brushitem.hxx>
22 #include <flyfrm.hxx>
23 #include <rootfrm.hxx>
24 #include <txtfrm.hxx>
25 #include <sectfrm.hxx>
26 #include <section.hxx>
27 #include <viewsh.hxx>
28 #include <viewopt.hxx>
29 #include <doc.hxx>
30 #include <frmatr.hxx>
31 #include <pagefrm.hxx>
32 #include <pagedesc.hxx>
33 #include <fmtanchr.hxx>
34 #include <fldbas.hxx>
35 #include <dcontact.hxx>
36 #include <accmap.hxx>
37 #include "accfrmobjslist.hxx"
38 #include "accfrmobjmap.hxx"
39 #include "accframe.hxx"
40 
41 using namespace sw::access;
42 
43 // Regarding visibility (or in terms of accessibility: regarding the showing
44 // state): A frame is visible and therefore contained in the tree if its frame
45 // size overlaps with the visible area. The bounding box however is the
46 // frame's paint area.
48  const SwRect& rVisArea,
49  const SwFrame *pFrame,
50  bool bInPagePreview )
51 {
52  sal_Int32 nCount = 0;
53 
54  const SwAccessibleChildSList aVisList( rVisArea, *pFrame, rAccMap );
55 
57  while( aIter != aVisList.end() )
58  {
59  const SwAccessibleChild& rLower = *aIter;
60  if( rLower.IsAccessible( bInPagePreview ) )
61  {
62  nCount++;
63  }
64  else if( rLower.GetSwFrame() )
65  {
66  // There are no unaccessible SdrObjects that count
67  nCount += GetChildCount( rAccMap,
68  rVisArea, rLower.GetSwFrame(),
69  bInPagePreview );
70  }
71  ++aIter;
72  }
73 
74  return nCount;
75 }
76 
78  SwAccessibleMap& rAccMap,
79  const SwRect& rVisArea,
80  const SwFrame& rFrame,
81  sal_Int32& rPos,
82  bool bInPagePreview )
83 {
84  SwAccessibleChild aRet;
85 
86  if( rPos >= 0 )
87  {
89  {
90  // We need a sorted list here
91  const SwAccessibleChildMap aVisMap( rVisArea, rFrame, rAccMap );
93  while( aIter != aVisMap.cend() && !aRet.IsValid() )
94  {
95  const SwAccessibleChild& rLower = (*aIter).second;
96  if( rLower.IsAccessible( bInPagePreview ) )
97  {
98  if( 0 == rPos )
99  aRet = rLower;
100  else
101  rPos--;
102  }
103  else if( rLower.GetSwFrame() )
104  {
105  // There are no unaccessible SdrObjects that count
106  aRet = GetChild( rAccMap,
107  rVisArea, *(rLower.GetSwFrame()), rPos,
108  bInPagePreview );
109  }
110  ++aIter;
111  }
112  }
113  else
114  {
115  // The unsorted list is sorted enough, because it returns lower
116  // frames in the correct order.
117  const SwAccessibleChildSList aVisList( rVisArea, rFrame, rAccMap );
118  SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
119  while( aIter != aVisList.end() && !aRet.IsValid() )
120  {
121  const SwAccessibleChild& rLower = *aIter;
122  if( rLower.IsAccessible( bInPagePreview ) )
123  {
124  if( 0 == rPos )
125  aRet = rLower;
126  else
127  rPos--;
128  }
129  else if( rLower.GetSwFrame() )
130  {
131  // There are no unaccessible SdrObjects that count
132  aRet = GetChild( rAccMap,
133  rVisArea, *(rLower.GetSwFrame()), rPos,
134  bInPagePreview );
135  }
136  ++aIter;
137  }
138  }
139  }
140 
141  return aRet;
142 }
143 
145  SwAccessibleMap& rAccMap,
146  const SwRect& rVisArea,
147  const SwFrame& rFrame,
148  const SwAccessibleChild& rChild,
149  sal_Int32& rPos,
150  bool bInPagePreview )
151 {
152  bool bFound = false;
153 
155  {
156  // We need a sorted list here
157  const SwAccessibleChildMap aVisMap( rVisArea, rFrame, rAccMap );
158  SwAccessibleChildMap::const_iterator aIter( aVisMap.cbegin() );
159  while( aIter != aVisMap.cend() && !bFound )
160  {
161  const SwAccessibleChild& rLower = (*aIter).second;
162  if( rLower.IsAccessible( bInPagePreview ) )
163  {
164  if( rChild == rLower )
165  bFound = true;
166  else
167  rPos++;
168  }
169  else if( rLower.GetSwFrame() )
170  {
171  // There are no unaccessible SdrObjects that count
172  bFound = GetChildIndex( rAccMap,
173  rVisArea, *(rLower.GetSwFrame()), rChild,
174  rPos, bInPagePreview );
175  }
176  ++aIter;
177  }
178  }
179  else
180  {
181  // The unsorted list is sorted enough, because it returns lower
182  // frames in the correct order.
183 
184  const SwAccessibleChildSList aVisList( rVisArea, rFrame, rAccMap );
185  SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
186  while( aIter != aVisList.end() && !bFound )
187  {
188  const SwAccessibleChild& rLower = *aIter;
189  if( rLower.IsAccessible( bInPagePreview ) )
190  {
191  if( rChild == rLower )
192  bFound = true;
193  else
194  rPos++;
195  }
196  else if( rLower.GetSwFrame() )
197  {
198  // There are no unaccessible SdrObjects that count
199  bFound = GetChildIndex( rAccMap,
200  rVisArea, *(rLower.GetSwFrame()), rChild,
201  rPos, bInPagePreview );
202  }
203  ++aIter;
204  }
205  }
206 
207  return bFound;
208 }
209 
211  const SwFrame& rFrame,
212  const Point& rPixPos,
213  bool bInPagePreview,
214  SwAccessibleMap& rAccMap )
215 {
216  SwAccessibleChild aRet;
217 
219  {
220  // We need a sorted list here, and we have to reverse iterate,
221  // because objects in front should be returned.
222  const SwAccessibleChildMap aVisMap( rVisArea, rFrame, rAccMap );
224  while( aRIter != aVisMap.crend() && !aRet.IsValid() )
225  {
226  const SwAccessibleChild& rLower = (*aRIter).second;
227  // A frame is returned if it's frame size is inside the visarea
228  // and the position is inside the frame's paint area.
229  if( rLower.IsAccessible( bInPagePreview ) )
230  {
231  SwRect aLogBounds( rLower.GetBounds( rAccMap ) );
232  if( !aLogBounds.IsEmpty() )
233  {
234  tools::Rectangle aPixBounds( rAccMap.CoreToPixel( aLogBounds.SVRect() ) );
235  if( aPixBounds.IsInside( rPixPos ) )
236  aRet = rLower;
237  }
238  }
239  else if( rLower.GetSwFrame() )
240  {
241  // There are no unaccessible SdrObjects that count
242  aRet = GetChildAtPixel( rVisArea, *(rLower.GetSwFrame()), rPixPos,
243  bInPagePreview, rAccMap );
244  }
245  ++aRIter;
246  }
247  }
248  else
249  {
250  // The unsorted list is sorted enough, because it returns lower
251  // frames in the correct order. Moreover, we can iterate forward,
252  // because the lowers don't overlap!
253  const SwAccessibleChildSList aVisList( rVisArea, rFrame, rAccMap );
254  SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
255  while( aIter != aVisList.end() && !aRet.IsValid() )
256  {
257  const SwAccessibleChild& rLower = *aIter;
258  // A frame is returned if it's frame size is inside the visarea
259  // and the position is inside the frame's paint area.
260  if( rLower.IsAccessible( bInPagePreview ) )
261  {
262  SwRect aLogBounds( rLower.GetBounds( rAccMap ) );
263  if( !aLogBounds.IsEmpty() )
264  {
265  tools::Rectangle aPixBounds( rAccMap.CoreToPixel( aLogBounds.SVRect() ) );
266  if( aPixBounds.IsInside( rPixPos ) )
267  aRet = rLower;
268  }
269  }
270  else if( rLower.GetSwFrame() )
271  {
272  // There are no unaccessible SdrObjects that count
273  aRet = GetChildAtPixel( rVisArea, *(rLower.GetSwFrame()), rPixPos,
274  bInPagePreview, rAccMap );
275  }
276  ++aIter;
277  }
278  }
279 
280  return aRet;
281 }
282 
284  const SwRect& rVisArea,
285  const SwFrame& rFrame,
286  std::list< SwAccessibleChild >& rChildren,
287  bool bInPagePreview )
288 {
290  {
291  // We need a sorted list here
292  const SwAccessibleChildMap aVisMap( rVisArea, rFrame, rAccMap );
293  SwAccessibleChildMap::const_iterator aIter( aVisMap.cbegin() );
294  while( aIter != aVisMap.cend() )
295  {
296  const SwAccessibleChild& rLower = (*aIter).second;
297  if( rLower.IsAccessible( bInPagePreview ) )
298  {
299  rChildren.push_back( rLower );
300  }
301  else if( rLower.GetSwFrame() )
302  {
303  // There are no unaccessible SdrObjects that count
304  GetChildren( rAccMap, rVisArea, *(rLower.GetSwFrame()),
305  rChildren, bInPagePreview );
306  }
307  ++aIter;
308  }
309  }
310  else
311  {
312  // The unsorted list is sorted enough, because it returns lower
313  // frames in the correct order.
314  const SwAccessibleChildSList aVisList( rVisArea, rFrame, rAccMap );
315  SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
316  while( aIter != aVisList.end() )
317  {
318  const SwAccessibleChild& rLower = *aIter;
319  if( rLower.IsAccessible( bInPagePreview ) )
320  {
321  rChildren.push_back( rLower );
322  }
323  else if( rLower.GetSwFrame() )
324  {
325  // There are no unaccessible SdrObjects that count
326  GetChildren( rAccMap, rVisArea, *(rLower.GetSwFrame()),
327  rChildren, bInPagePreview );
328  }
329  ++aIter;
330  }
331  }
332 }
333 
335  const SwFrame *pFrame )
336 {
337  if( !pFrame )
338  pFrame = GetFrame();
339 
340  SwAccessibleChild aFrame( pFrame );
341  SwRect aBounds( aFrame.GetBounds( rAccMap ).Intersection( maVisArea ) );
342  return aBounds;
343 }
344 
346 {
347  const SwFrame *pFrame = GetFrame();
348  if( !pFrame )
349  return false;
350 
351  OSL_ENSURE( pVSh, "no view shell" );
352  if( pVSh && (pVSh->GetViewOptions()->IsReadonly() ||
353  pVSh->IsPreview()) )
354  return false;
355 
356  if( !pFrame->IsRootFrame() && pFrame->IsProtected() )
357  return false;
358 
359  return true;
360 }
361 
362 bool SwAccessibleFrame::IsOpaque( SwViewShell const *pVSh ) const
363 {
364  SwAccessibleChild aFrame( GetFrame() );
365  if( !aFrame.GetSwFrame() )
366  return false;
367 
368  OSL_ENSURE( pVSh, "no view shell" );
369  if( !pVSh )
370  return false;
371 
372  const SwViewOption *pVOpt = pVSh->GetViewOptions();
373  do
374  {
375  const SwFrame *pFrame = aFrame.GetSwFrame();
376  if( pFrame->IsRootFrame() )
377  return true;
378 
379  if( pFrame->IsPageFrame() && !pVOpt->IsPageBack() )
380  return false;
381 
382  const SvxBrushItem &rBack = pFrame->GetAttrSet()->GetBackground();
383  if( !rBack.GetColor().GetTransparency() ||
384  rBack.GetGraphicPos() != GPOS_NONE )
385  return true;
386 
387  // If a fly frame has a transparent background color, we have to consider the background.
388  // But a background color "no fill"/"auto fill" should *not* be considered.
389  if( pFrame->IsFlyFrame() &&
390  (rBack.GetColor().GetTransparency() != 0) &&
391  (rBack.GetColor() != COL_TRANSPARENT)
392  )
393  return true;
394 
395  if( pFrame->IsSctFrame() )
396  {
397  const SwSection* pSection = static_cast<const SwSectionFrame*>(pFrame)->GetSection();
398  if( pSection && ( TOX_HEADER_SECTION == pSection->GetType() ||
399  TOX_CONTENT_SECTION == pSection->GetType() ) &&
400  !pVOpt->IsReadonly() &&
402  return true;
403  }
404  if( pFrame->IsFlyFrame() )
405  aFrame = static_cast<const SwFlyFrame*>(pFrame)->GetAnchorFrame();
406  else
407  aFrame = pFrame->GetUpper();
408  } while( aFrame.GetSwFrame() && !aFrame.IsAccessible( IsInPagePreview() ) );
409 
410  return false;
411 }
412 
414  const SwFrame *pF,
415  bool bIsPagePreview ) :
416  maVisArea( rVisArea ),
417  mpFrame( pF ),
418  mbIsInPagePreview( bIsPagePreview )
419 {
420  assert(mpFrame);
421 }
422 
424 {
425 }
426 
428  bool bInPagePreview )
429 {
430  return rFrameOrObj.GetParent( bInPagePreview );
431 }
432 
434 {
435  sal_uInt16 nPageNum = GetFrame()->GetVirtPageNum();
436  SvxNumType nFormat = GetFrame()->FindPageFrame()->GetPageDesc()
438  if( SVX_NUM_NUMBER_NONE == nFormat )
439  nFormat = SVX_NUM_ARABIC;
440 
441  OUString sRet( FormatNumber( nPageNum, nFormat ) );
442  return sRet;
443 }
444 
446 {
447  return GetChildCount( rAccMap, maVisArea, mpFrame, IsInPagePreview() );
448 }
449 
451  SwAccessibleMap& rAccMap,
452  sal_Int32 nPos ) const
453 {
454  return SwAccessibleFrame::GetChild( rAccMap, maVisArea, *mpFrame, nPos, IsInPagePreview() );
455 }
456 
458  const sw::access::SwAccessibleChild& rChild ) const
459 {
460  sal_Int32 nPos = 0;
461  return GetChildIndex( rAccMap, maVisArea, *mpFrame, rChild, nPos, IsInPagePreview() )
462  ? nPos
463  : -1;
464 }
465 
467  const Point& rPos,
468  SwAccessibleMap& rAccMap ) const
469 {
470  return GetChildAtPixel( maVisArea, *mpFrame, rPos, IsInPagePreview(), rAccMap );
471 }
472 
474  std::list< sw::access::SwAccessibleChild >& rChildren ) const
475 {
476  GetChildren( rAccMap, maVisArea, *mpFrame, rChildren, IsInPagePreview() );
477 }
478 
480  const sw::access::SwAccessibleChild& rFrameOrObj ) const
481 {
482  return IsShowing( rFrameOrObj.GetBox( rAccMap ) );
483 }
484 
485 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SvxNumType GetNumberingType() const
Base class of the Writer layout elements.
Definition: frame.hxx:295
const SwFrame * mpFrame
Definition: accframe.hxx:40
const_reverse_iterator crbegin() const
bool IsRootFrame() const
Definition: frame.hxx:1150
const SvxBrushItem & GetBackground(bool=true) const
Definition: frmatr.hxx:58
SwRect GetBounds(const SwAccessibleMap &rAccMap) const
Definition: accfrmobj.cxx:275
GPOS_NONE
SVX_NUM_NUMBER_NONE
const_iterator cbegin() const
sal_uInt8 GetTransparency() const
const_reverse_iterator crend() const
bool IsPageBack() const
Definition: viewopt.hxx:292
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
static sal_Int32 GetChildCount(SwAccessibleMap &rAccMap, const SwRect &rVisArea, const SwFrame *pFrame, bool bInPagePreviewr)
Definition: accframe.cxx:47
bool IsInPagePreview() const
Definition: accframe.hxx:87
std::map< key_type, mapped_type, key_compare >::const_iterator const_iterator
SvxNumType
bool IsFlyFrame() const
Definition: frame.hxx:1186
constexpr::Color COL_TRANSPARENT(0xFF, 0xFF, 0xFF, 0xFF)
bool IsReadonly() const
Definition: viewopt.hxx:417
static sw::access::SwAccessibleChild GetChild(SwAccessibleMap &rAccMap, const SwRect &rVisArea, const SwFrame &rFrame, sal_Int32 &rPos, bool bInPagePreview)
Definition: accframe.cxx:77
SvxGraphicPosition GetGraphicPos() const
const SwFrame * GetFrame() const
Definition: accframe.hxx:103
std::map< key_type, mapped_type, key_compare >::const_reverse_iterator const_reverse_iterator
SwRect & Intersection(const SwRect &rRect)
Definition: swrect.cxx:57
SVX_NUM_ARABIC
OUString FormatNumber(sal_uInt32 nNum, SvxNumType nFormat, LanguageType nLang)
expand numbering
Definition: fldbas.cxx:444
bool IsSctFrame() const
Definition: frame.hxx:1190
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
bool IsOpaque(SwViewShell const *pVSh) const
Definition: accframe.cxx:362
sal_uInt16 GetVirtPageNum() const
Definition: trvlfrm.cxx:1805
const Color & GetColor() const
const SwFrame * GetSwFrame() const
Definition: accfrmobj.hxx:58
static void GetChildren(SwAccessibleMap &rAccMap, const SwRect &rVisArea, const SwFrame &rFrame, std::list< sw::access::SwAccessibleChild > &rChildren, bool bInPagePreview)
Definition: accframe.cxx:283
const_iterator begin() const
const SwFrame * GetParent(const bool bInPagePreview) const
Definition: accfrmobj.cxx:313
SwPageFrame * FindPageFrame()
Definition: frame.hxx:658
static bool IsIndexShadings()
Definition: viewopt.hxx:622
SwPageDesc * GetPageDesc()
Definition: pagefrm.hxx:128
bool IsPreview() const
Definition: viewsh.hxx:491
static bool GetChildIndex(SwAccessibleMap &rAccMap, const SwRect &rVisArea, const SwFrame &rFrame, const sw::access::SwAccessibleChild &rChild, sal_Int32 &rPos, bool bInPagePreview)
Definition: accframe.cxx:144
tools::Rectangle CoreToPixel(const tools::Rectangle &rRect) const
Definition: accmap.cxx:3211
SwLayoutFrame * GetUpper()
Definition: frame.hxx:656
bool IsInside(const Point &rPOINT) const
SwAccessibleFrame(const SwRect &rVisArea, const SwFrame *pFrame, bool bIsPagePreview)
Definition: accframe.cxx:413
const_iterator end() const
SwRect GetBounds(const SwAccessibleMap &rAccMap, const SwFrame *pFrame=nullptr)
Definition: accframe.cxx:334
virtual ~SwAccessibleFrame()
Definition: accframe.cxx:423
bool IsEditable(SwViewShell const *pVSh) const
Definition: accframe.cxx:345
OUString GetFormattedPageNumber() const
Definition: accframe.cxx:433
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:426
bool IsAccessible(bool bPagePreview) const
Definition: accfrmobj.cxx:124
const_iterator cend() const
const SwFrame * GetParent() const
Definition: accframe.hxx:155
static bool IsSortingRequired(const SwFrame &rFrame)
bool IsPageFrame() const
Definition: frame.hxx:1154
SwRect GetBox(const SwAccessibleMap &rAccMap) const
Definition: accfrmobj.cxx:224
SectionType GetType() const
Definition: section.hxx:171
sal_Int32 nPos
bool IsProtected() const
Is the Frame or rather the Section in which it lies protected?
Definition: trvlfrm.cxx:1621
static sw::access::SwAccessibleChild GetChildAtPixel(const SwRect &rVisArea, const SwFrame &rFrame, const Point &rPos, bool bInPagePreview, SwAccessibleMap &rAccMap)
Definition: accframe.cxx:210
bool IsShowing(const SwAccessibleMap &rAccMap, const sw::access::SwAccessibleChild &rFrameOrObj) const
Definition: accframe.cxx:479
const SvxNumberType & GetNumType() const
Definition: pagedesc.hxx:192