xref: /AOO41X/main/sw/source/core/access/accframe.cxx (revision 4d7c9de063a797b8b4f3d45e3561e82ad1f8ef1f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 
28 
29 #include <hintids.hxx>
30 #include <editeng/brshitem.hxx>
31 #include <flyfrm.hxx>
32 #include <rootfrm.hxx>
33 #include <txtfrm.hxx>
34 #include <sectfrm.hxx>
35 #include <pagefrm.hxx>
36 #include <section.hxx>
37 #include <viewsh.hxx>
38 #include <viewopt.hxx>
39 #include <doc.hxx>
40 #include <frmatr.hxx>
41 #include <pagefrm.hxx>
42 #include <pagedesc.hxx>
43 #include <fmtanchr.hxx>
44 #include <fldbas.hxx>
45 #include <dcontact.hxx>
46 #include <accmap.hxx>
47 #include <accfrmobjslist.hxx>
48 #include <accfrmobjmap.hxx>
49 #include <accframe.hxx>
50 
51 using namespace sw::access;
52 
53 // Regarding visibilily (or in terms of accessibility: regarding the showing
54 // state): A frame is visible and therfor contained in the tree if its frame
55 // size overlaps with the visible area. The bounding box however is the
56 // frame's paint area.
GetChildCount(SwAccessibleMap & rAccMap,const SwRect & rVisArea,const SwFrm * pFrm,sal_Bool bInPagePreview)57 /* static */ sal_Int32 SwAccessibleFrame::GetChildCount( SwAccessibleMap& rAccMap,
58                                                          const SwRect& rVisArea,
59                                                          const SwFrm *pFrm,
60                                                          sal_Bool bInPagePreview )
61 {
62     sal_Int32 nCount = 0;
63 
64     // const SwAccessibleChildSList aVisList( rVisArea, *pFrm, rAccMap );
65     const SwAccessibleChildSList aVisList( pFrm->PaintArea(), *pFrm, rAccMap );
66 
67     SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
68     while( aIter != aVisList.end() )
69     {
70         const SwAccessibleChild& rLower = *aIter;
71         if( rLower.IsAccessible( bInPagePreview ) )
72         {
73             nCount++;
74         }
75         else if( rLower.GetSwFrm() )
76         {
77             // There are no unaccessible SdrObjects that count
78             nCount += GetChildCount( rAccMap,
79                                      rVisArea, rLower.GetSwFrm(),
80                                      bInPagePreview );
81         }
82         ++aIter;
83     }
84 
85     return nCount;
86 }
87 
GetChild(SwAccessibleMap & rAccMap,const SwRect & rVisArea,const SwFrm & rFrm,sal_Int32 & rPos,sal_Bool bInPagePreview)88 /* static */ SwAccessibleChild SwAccessibleFrame::GetChild(
89                                                 SwAccessibleMap& rAccMap,
90                                                 const SwRect& rVisArea,
91                                                 const SwFrm& rFrm,
92                                                 sal_Int32& rPos,
93                                                 sal_Bool bInPagePreview )
94 {
95     SwAccessibleChild aRet;
96 
97     if( rPos >= 0 )
98     {
99         if( SwAccessibleChildMap::IsSortingRequired( rFrm ) )
100         {
101             // We need a sorted list here
102             const SwAccessibleChildMap aVisMap( rVisArea, rFrm, rAccMap );
103             SwAccessibleChildMap::const_iterator aIter( aVisMap.begin() );
104             while( aIter != aVisMap.end() && !aRet.IsValid() )
105             {
106                 const SwAccessibleChild& rLower = (*aIter).second;
107                 if( rLower.IsAccessible( bInPagePreview ) )
108                 {
109                     if( 0 == rPos )
110                         aRet = rLower;
111                     else
112                         rPos--;
113                 }
114                 else if( rLower.GetSwFrm() )
115                 {
116                     // There are no unaccessible SdrObjects that count
117                     aRet = GetChild( rAccMap,
118                                      rVisArea, *(rLower.GetSwFrm()), rPos,
119                                      bInPagePreview );
120                 }
121                 ++aIter;
122             }
123         }
124         else
125         {
126             // The unsorted list is sorted enough, because it return lower
127             // frames in the correct order.
128             const SwAccessibleChildSList aVisList( rVisArea, rFrm, rAccMap );
129             SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
130             while( aIter != aVisList.end() && !aRet.IsValid() )
131             {
132                 const SwAccessibleChild& rLower = *aIter;
133                 if( rLower.IsAccessible( bInPagePreview ) )
134                 {
135                     if( 0 == rPos )
136                         aRet = rLower;
137                     else
138                         rPos--;
139                 }
140                 else if( rLower.GetSwFrm() )
141                 {
142                     // There are no unaccessible SdrObjects that count
143                     aRet = GetChild( rAccMap,
144                                      rVisArea, *(rLower.GetSwFrm()), rPos,
145                                      bInPagePreview );
146                 }
147                 ++aIter;
148             }
149         }
150     }
151 
152     return aRet;
153 }
154 
GetChildIndex(SwAccessibleMap & rAccMap,const SwRect & rVisArea,const SwFrm & rFrm,const SwAccessibleChild & rChild,sal_Int32 & rPos,sal_Bool bInPagePreview)155 /* static */ sal_Bool SwAccessibleFrame::GetChildIndex(
156                                                 SwAccessibleMap& rAccMap,
157                                                 const SwRect& rVisArea,
158                                                 const SwFrm& rFrm,
159                                                 const SwAccessibleChild& rChild,
160                                                 sal_Int32& rPos,
161                                                 sal_Bool bInPagePreview )
162 {
163     sal_Bool bFound = sal_False;
164 
165     if( SwAccessibleChildMap::IsSortingRequired( rFrm ) )
166     {
167         // We need a sorted list here
168         // const SwAccessibleChildMap aVisMap( rVisArea, rFrm, rAccMap );
169         const SwAccessibleChildMap aVisMap( rFrm.PaintArea(), rFrm, rAccMap );
170         SwAccessibleChildMap::const_iterator aIter( aVisMap.begin() );
171         while( aIter != aVisMap.end() && !bFound )
172         {
173             const SwAccessibleChild& rLower = (*aIter).second;
174             if( rLower.IsAccessible( bInPagePreview ) )
175             {
176                 if( rChild == rLower )
177                     bFound = sal_True;
178                 else
179                     rPos++;
180             }
181             else if( rLower.GetSwFrm() )
182             {
183                 // There are no unaccessible SdrObjects that count
184                 bFound = GetChildIndex( rAccMap,
185                                         rVisArea, *(rLower.GetSwFrm()), rChild,
186                                         rPos, bInPagePreview );
187             }
188             ++aIter;
189         }
190     }
191     else
192     {
193         // The unsorted list is sorted enough, because it return lower
194         // frames in the correct order.
195 
196         // const SwAccessibleChildSList aVisList( rVisArea, rFrm, rAccMap );
197         const SwAccessibleChildSList aVisList( rFrm.PaintArea(), rFrm, rAccMap );
198 
199         SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
200         while( aIter != aVisList.end() && !bFound )
201         {
202             const SwAccessibleChild& rLower = *aIter;
203             if( rLower.IsAccessible( bInPagePreview ) )
204             {
205                 if( rChild == rLower )
206                     bFound = sal_True;
207                 else
208                     rPos++;
209             }
210             else if( rLower.GetSwFrm() )
211             {
212                 // There are no unaccessible SdrObjects that count
213                 bFound = GetChildIndex( rAccMap,
214                                         rVisArea, *(rLower.GetSwFrm()), rChild,
215                                         rPos, bInPagePreview );
216             }
217             ++aIter;
218         }
219     }
220 
221     return bFound;
222 }
223 
GetChildAtPixel(const SwRect & rVisArea,const SwFrm & rFrm,const Point & rPixPos,sal_Bool bInPagePreview,SwAccessibleMap & rAccMap)224 SwAccessibleChild SwAccessibleFrame::GetChildAtPixel( const SwRect& rVisArea,
225                                           const SwFrm& rFrm,
226                                           const Point& rPixPos,
227                                           sal_Bool bInPagePreview,
228                                           SwAccessibleMap& rAccMap )
229 {
230     SwAccessibleChild aRet;
231 
232     if( SwAccessibleChildMap::IsSortingRequired( rFrm ) )
233     {
234         // We need a sorted list here, and we have to reverse iterate,
235         // because objects in front should be returned.
236         const SwAccessibleChildMap aVisMap( rVisArea, rFrm, rAccMap );
237         SwAccessibleChildMap::const_reverse_iterator aRIter( aVisMap.rbegin() );
238         while( aRIter != aVisMap.rend() && !aRet.IsValid() )
239         {
240             const SwAccessibleChild& rLower = (*aRIter).second;
241             // A frame is returned if it's frame size is inside the visarea
242             // and the positiion is inside the frame's paint area.
243             if( rLower.IsAccessible( bInPagePreview ) )
244             {
245                 SwRect aLogBounds( rLower.GetBounds( rAccMap ) );
246                 if( !aLogBounds.IsEmpty() )
247                 {
248                     Rectangle aPixBounds( rAccMap.CoreToPixel( aLogBounds.SVRect() ) );
249                     if( aPixBounds.IsInside( rPixPos ) )
250                         aRet = rLower;
251                 }
252             }
253             else if( rLower.GetSwFrm() )
254             {
255                 // There are no unaccessible SdrObjects that count
256                 aRet = GetChildAtPixel( rVisArea, *(rLower.GetSwFrm()), rPixPos,
257                                         bInPagePreview, rAccMap );
258             }
259             aRIter++;
260         }
261     }
262     else
263     {
264         // The unsorted list is sorted enough, because it returns lower
265         // frames in the correct order. Morover, we can iterate forward,
266         // because the lowers don't overlap!
267         const SwAccessibleChildSList aVisList( rVisArea, rFrm, rAccMap );
268         SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
269         while( aIter != aVisList.end() && !aRet.IsValid() )
270         {
271             const SwAccessibleChild& rLower = *aIter;
272             // A frame is returned if it's frame size is inside the visarea
273             // and the positiion is inside the frame's paint area.
274             if( rLower.IsAccessible( bInPagePreview ) )
275             {
276                 SwRect aLogBounds( rLower.GetBounds( rAccMap ) );
277                 if( !aLogBounds.IsEmpty() )
278                 {
279                     Rectangle aPixBounds( rAccMap.CoreToPixel( aLogBounds.SVRect() ) );
280                     if( aPixBounds.IsInside( rPixPos ) )
281                         aRet = rLower;
282                 }
283             }
284             else if( rLower.GetSwFrm() )
285             {
286                 // There are no unaccessible SdrObjects that count
287                 aRet = GetChildAtPixel( rVisArea, *(rLower.GetSwFrm()), rPixPos,
288                                    bInPagePreview, rAccMap );
289             }
290             ++aIter;
291         }
292     }
293 
294     return aRet;
295 }
296 
GetChildren(SwAccessibleMap & rAccMap,const SwRect & rVisArea,const SwFrm & rFrm,::std::list<SwAccessibleChild> & rChildren,sal_Bool bInPagePreview)297 /* static */ void SwAccessibleFrame::GetChildren( SwAccessibleMap& rAccMap,
298                                                   const SwRect& rVisArea,
299                                                   const SwFrm& rFrm,
300                                                   ::std::list< SwAccessibleChild >& rChildren,
301                                                   sal_Bool bInPagePreview )
302 {
303     if( SwAccessibleChildMap::IsSortingRequired( rFrm ) )
304     {
305         // We need a sorted list here
306         const SwAccessibleChildMap aVisMap( rVisArea, rFrm, rAccMap );
307         SwAccessibleChildMap::const_iterator aIter( aVisMap.begin() );
308         while( aIter != aVisMap.end() )
309         {
310             const SwAccessibleChild& rLower = (*aIter).second;
311             if( rLower.IsAccessible( bInPagePreview ) )
312             {
313                 rChildren.push_back( rLower );
314             }
315             else if( rLower.GetSwFrm() )
316             {
317                 // There are no unaccessible SdrObjects that count
318                 GetChildren( rAccMap, rVisArea, *(rLower.GetSwFrm()),
319                              rChildren, bInPagePreview );
320             }
321             ++aIter;
322         }
323     }
324     else
325     {
326         // The unsorted list is sorted enough, because it return lower
327         // frames in the correct order.
328         const SwAccessibleChildSList aVisList( rVisArea, rFrm, rAccMap );
329         SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
330         while( aIter != aVisList.end() )
331         {
332             const SwAccessibleChild& rLower = *aIter;
333             if( rLower.IsAccessible( bInPagePreview ) )
334             {
335                 rChildren.push_back( rLower );
336             }
337             else if( rLower.GetSwFrm() )
338             {
339                 // There are no unaccessible SdrObjects that count
340                 GetChildren( rAccMap, rVisArea, *(rLower.GetSwFrm()),
341                              rChildren, bInPagePreview );
342             }
343             ++aIter;
344         }
345     }
346 }
347 
GetBounds(const SwAccessibleMap & rAccMap,const SwFrm * pFrm)348 SwRect SwAccessibleFrame::GetBounds( const SwAccessibleMap& rAccMap,
349                                      const SwFrm *pFrm )
350 {
351     if( !pFrm )
352         pFrm = GetFrm();
353 
354     SwAccessibleChild aFrm( pFrm );
355     SwRect aBounds( aFrm.GetBounds( rAccMap ).Intersection( maVisArea ) );
356     return aBounds;
357 }
358 
IsEditable(ViewShell * pVSh) const359 sal_Bool SwAccessibleFrame::IsEditable( ViewShell *pVSh ) const
360 {
361     const SwFrm *pFrm = GetFrm();
362     if( !pFrm )
363         return sal_False;
364 
365     ASSERT( pVSh, "no view shell" );
366     if( pVSh && (pVSh->GetViewOptions()->IsReadonly() ||
367                  pVSh->IsPreView()) )
368         return sal_False;
369 
370     if( !pFrm->IsRootFrm() && pFrm->IsProtected() )
371         return sal_False;
372 
373     return sal_True;
374 }
375 
IsOpaque(ViewShell * pVSh) const376 sal_Bool SwAccessibleFrame::IsOpaque( ViewShell *pVSh ) const
377 {
378     SwAccessibleChild aFrm( GetFrm() );
379     if( !aFrm.GetSwFrm() )
380         return sal_False;
381 
382     ASSERT( pVSh, "no view shell" );
383     if( !pVSh )
384         return sal_False;
385 
386     const SwViewOption *pVOpt = pVSh->GetViewOptions();
387     do
388     {
389         const SwFrm *pFrm = aFrm.GetSwFrm();
390         if( pFrm->IsRootFrm() )
391             return sal_True;
392 
393         if( pFrm->IsPageFrm() && !pVOpt->IsPageBack() )
394             return sal_False;
395 
396         const SvxBrushItem &rBack = pFrm->GetAttrSet()->GetBackground();
397         if( !rBack.GetColor().GetTransparency() ||
398              rBack.GetGraphicPos() != GPOS_NONE )
399             return sal_True;
400 
401         /// OD 20.08.2002 #99657#
402         ///     If a fly frame has a transparent background color, we have
403         ///     to consider the background.
404         ///     But a background color "no fill"/"auto fill" has *not* to be considered.
405         if( pFrm->IsFlyFrm() &&
406             (rBack.GetColor().GetTransparency() != 0) &&
407             (rBack.GetColor() != COL_TRANSPARENT)
408           )
409             return sal_True;
410 
411         if( pFrm->IsSctFrm() )
412         {
413             const SwSection* pSection = ((SwSectionFrm*)pFrm)->GetSection();
414             if( pSection && ( TOX_HEADER_SECTION == pSection->GetType() ||
415                 TOX_CONTENT_SECTION == pSection->GetType() ) &&
416                 !pVOpt->IsReadonly() &&
417                 SwViewOption::IsIndexShadings() )
418                 return sal_True;
419         }
420         if( pFrm->IsFlyFrm() )
421             aFrm = static_cast<const SwFlyFrm*>(pFrm)->GetAnchorFrm();
422         else
423             aFrm = pFrm->GetUpper();
424     } while( aFrm.GetSwFrm() && !aFrm.IsAccessible( IsInPagePreview() ) );
425 
426     return sal_False;
427 }
428 
SwAccessibleFrame(const SwRect & rVisArea,const SwFrm * pF,sal_Bool bIsPagePreview)429 SwAccessibleFrame::SwAccessibleFrame( const SwRect& rVisArea,
430                                       const SwFrm *pF,
431                                       sal_Bool bIsPagePreview ) :
432     maVisArea( rVisArea ),
433     mpFrm( pF ),
434     mbIsInPagePreview( bIsPagePreview ),
435     bIsAccDocUse( sal_False )
436 {
437 }
438 
~SwAccessibleFrame()439 SwAccessibleFrame::~SwAccessibleFrame()
440 {
441 }
442 
GetParent(const SwAccessibleChild & rFrmOrObj,sal_Bool bInPagePreview)443 /* static */ const SwFrm* SwAccessibleFrame::GetParent( const SwAccessibleChild& rFrmOrObj,
444                                                         sal_Bool bInPagePreview )
445 {
446     return rFrmOrObj.GetParent( bInPagePreview );
447 }
448 
GetFormattedPageNumber() const449 String SwAccessibleFrame::GetFormattedPageNumber() const
450 {
451     sal_uInt16 nPageNum = GetFrm()->GetVirtPageNum();
452     sal_uInt32 nFmt = GetFrm()->FindPageFrm()->GetPageDesc()
453                               ->GetNumType().GetNumberingType();
454     if( SVX_NUM_NUMBER_NONE == nFmt )
455         nFmt = SVX_NUM_ARABIC;
456 
457     String sRet( FormatNumber( nPageNum, nFmt ) );
458     return sRet;
459 }
460 
GetChildCount(SwAccessibleMap & rAccMap) const461 sal_Int32 SwAccessibleFrame::GetChildCount( SwAccessibleMap& rAccMap ) const
462 {
463     return GetChildCount( rAccMap, maVisArea, mpFrm, IsInPagePreview() );
464 }
465 
GetChild(SwAccessibleMap & rAccMap,sal_Int32 nPos) const466 sw::access::SwAccessibleChild SwAccessibleFrame::GetChild(
467                                                 SwAccessibleMap& rAccMap,
468                                                 sal_Int32 nPos ) const
469 {
470     return SwAccessibleFrame::GetChild( rAccMap, maVisArea, *mpFrm, nPos, IsInPagePreview() );
471 }
472 
GetChildIndex(SwAccessibleMap & rAccMap,const sw::access::SwAccessibleChild & rChild) const473 sal_Int32 SwAccessibleFrame::GetChildIndex( SwAccessibleMap& rAccMap,
474                                             const sw::access::SwAccessibleChild& rChild ) const
475 {
476     sal_Int32 nPos = 0;
477     return GetChildIndex( rAccMap, maVisArea, *mpFrm, rChild, nPos, IsInPagePreview() )
478            ? nPos
479            : -1L;
480 }
481 
GetChildAtPixel(const Point & rPos,SwAccessibleMap & rAccMap) const482 sw::access::SwAccessibleChild SwAccessibleFrame::GetChildAtPixel(
483                                                 const Point& rPos,
484                                                 SwAccessibleMap& rAccMap ) const
485 {
486     return GetChildAtPixel( maVisArea, *mpFrm, rPos, IsInPagePreview(), rAccMap );
487 }
488 
GetChildren(SwAccessibleMap & rAccMap,::std::list<sw::access::SwAccessibleChild> & rChildren) const489 void SwAccessibleFrame::GetChildren( SwAccessibleMap& rAccMap,
490                                      ::std::list< sw::access::SwAccessibleChild >& rChildren ) const
491 {
492     GetChildren( rAccMap, maVisArea, *mpFrm, rChildren, IsInPagePreview() );
493 }
494 
IsShowing(const SwAccessibleMap & rAccMap,const sw::access::SwAccessibleChild & rFrmOrObj) const495 sal_Bool SwAccessibleFrame::IsShowing( const SwAccessibleMap& rAccMap,
496                                        const sw::access::SwAccessibleChild& rFrmOrObj ) const
497 {
498     return IsShowing( rFrmOrObj.GetBox( rAccMap ) );
499 }
500 
501