xref: /trunk/main/sw/source/core/access/accframe.cxx (revision ffad8df045fe8db79e3e50f731c1fa6ab6501c83)
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.
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 
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 
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         //IAccessibility2 Implementation 2009-----
169         // const SwAccessibleChildMap aVisMap( rVisArea, rFrm, rAccMap );
170         const SwAccessibleChildMap aVisMap( rFrm.PaintArea(), rFrm, rAccMap );
171         //-----IAccessibility2 Implementation 2009
172         SwAccessibleChildMap::const_iterator aIter( aVisMap.begin() );
173         while( aIter != aVisMap.end() && !bFound )
174         {
175             const SwAccessibleChild& rLower = (*aIter).second;
176             if( rLower.IsAccessible( bInPagePreview ) )
177             {
178                 if( rChild == rLower )
179                     bFound = sal_True;
180                 else
181                     rPos++;
182             }
183             else if( rLower.GetSwFrm() )
184             {
185                 // There are no unaccessible SdrObjects that count
186                 bFound = GetChildIndex( rAccMap,
187                                         rVisArea, *(rLower.GetSwFrm()), rChild,
188                                         rPos, bInPagePreview );
189             }
190             ++aIter;
191         }
192     }
193     else
194     {
195         // The unsorted list is sorted enough, because it return lower
196         // frames in the correct order.
197 
198         //IAccessibility2 Implementation 2009-----
199         // const SwAccessibleChildSList aVisList( rVisArea, rFrm, rAccMap );
200         const SwAccessibleChildSList aVisList( rFrm.PaintArea(), rFrm, rAccMap );
201         //-----IAccessibility2 Implementation 2009
202 
203         SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
204         while( aIter != aVisList.end() && !bFound )
205         {
206             const SwAccessibleChild& rLower = *aIter;
207             if( rLower.IsAccessible( bInPagePreview ) )
208             {
209                 if( rChild == rLower )
210                     bFound = sal_True;
211                 else
212                     rPos++;
213             }
214             else if( rLower.GetSwFrm() )
215             {
216                 // There are no unaccessible SdrObjects that count
217                 bFound = GetChildIndex( rAccMap,
218                                         rVisArea, *(rLower.GetSwFrm()), rChild,
219                                         rPos, bInPagePreview );
220             }
221             ++aIter;
222         }
223     }
224 
225     return bFound;
226 }
227 
228 SwAccessibleChild SwAccessibleFrame::GetChildAtPixel( const SwRect& rVisArea,
229                                           const SwFrm& rFrm,
230                                           const Point& rPixPos,
231                                           sal_Bool bInPagePreview,
232                                           SwAccessibleMap& rAccMap )
233 {
234     SwAccessibleChild aRet;
235 
236     if( SwAccessibleChildMap::IsSortingRequired( rFrm ) )
237     {
238         // We need a sorted list here, and we have to reverse iterate,
239         // because objects in front should be returned.
240         const SwAccessibleChildMap aVisMap( rVisArea, rFrm, rAccMap );
241         SwAccessibleChildMap::const_reverse_iterator aRIter( aVisMap.rbegin() );
242         while( aRIter != aVisMap.rend() && !aRet.IsValid() )
243         {
244             const SwAccessibleChild& rLower = (*aRIter).second;
245             // A frame is returned if it's frame size is inside the visarea
246             // and the positiion is inside the frame's paint area.
247             if( rLower.IsAccessible( bInPagePreview ) )
248             {
249                 SwRect aLogBounds( rLower.GetBounds( rAccMap ) );
250                 if( !aLogBounds.IsEmpty() )
251                 {
252                     Rectangle aPixBounds( rAccMap.CoreToPixel( aLogBounds.SVRect() ) );
253                     if( aPixBounds.IsInside( rPixPos ) )
254                         aRet = rLower;
255                 }
256             }
257             else if( rLower.GetSwFrm() )
258             {
259                 // There are no unaccessible SdrObjects that count
260                 aRet = GetChildAtPixel( rVisArea, *(rLower.GetSwFrm()), rPixPos,
261                                         bInPagePreview, rAccMap );
262             }
263             aRIter++;
264         }
265     }
266     else
267     {
268         // The unsorted list is sorted enough, because it returns lower
269         // frames in the correct order. Morover, we can iterate forward,
270         // because the lowers don't overlap!
271         const SwAccessibleChildSList aVisList( rVisArea, rFrm, rAccMap );
272         SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
273         while( aIter != aVisList.end() && !aRet.IsValid() )
274         {
275             const SwAccessibleChild& rLower = *aIter;
276             // A frame is returned if it's frame size is inside the visarea
277             // and the positiion is inside the frame's paint area.
278             if( rLower.IsAccessible( bInPagePreview ) )
279             {
280                 SwRect aLogBounds( rLower.GetBounds( rAccMap ) );
281                 if( !aLogBounds.IsEmpty() )
282                 {
283                     Rectangle aPixBounds( rAccMap.CoreToPixel( aLogBounds.SVRect() ) );
284                     if( aPixBounds.IsInside( rPixPos ) )
285                         aRet = rLower;
286                 }
287             }
288             else if( rLower.GetSwFrm() )
289             {
290                 // There are no unaccessible SdrObjects that count
291                 aRet = GetChildAtPixel( rVisArea, *(rLower.GetSwFrm()), rPixPos,
292                                    bInPagePreview, rAccMap );
293             }
294             ++aIter;
295         }
296     }
297 
298     return aRet;
299 }
300 
301 /* static */ void SwAccessibleFrame::GetChildren( SwAccessibleMap& rAccMap,
302                                                   const SwRect& rVisArea,
303                                                   const SwFrm& rFrm,
304                                                   ::std::list< SwAccessibleChild >& rChildren,
305                                                   sal_Bool bInPagePreview )
306 {
307     if( SwAccessibleChildMap::IsSortingRequired( rFrm ) )
308     {
309         // We need a sorted list here
310         const SwAccessibleChildMap aVisMap( rVisArea, rFrm, rAccMap );
311         SwAccessibleChildMap::const_iterator aIter( aVisMap.begin() );
312         while( aIter != aVisMap.end() )
313         {
314             const SwAccessibleChild& rLower = (*aIter).second;
315             if( rLower.IsAccessible( bInPagePreview ) )
316             {
317                 rChildren.push_back( rLower );
318             }
319             else if( rLower.GetSwFrm() )
320             {
321                 // There are no unaccessible SdrObjects that count
322                 GetChildren( rAccMap, rVisArea, *(rLower.GetSwFrm()),
323                              rChildren, bInPagePreview );
324             }
325             ++aIter;
326         }
327     }
328     else
329     {
330         // The unsorted list is sorted enough, because it return lower
331         // frames in the correct order.
332         const SwAccessibleChildSList aVisList( rVisArea, rFrm, rAccMap );
333         SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
334         while( aIter != aVisList.end() )
335         {
336             const SwAccessibleChild& rLower = *aIter;
337             if( rLower.IsAccessible( bInPagePreview ) )
338             {
339                 rChildren.push_back( rLower );
340             }
341             else if( rLower.GetSwFrm() )
342             {
343                 // There are no unaccessible SdrObjects that count
344                 GetChildren( rAccMap, rVisArea, *(rLower.GetSwFrm()),
345                              rChildren, bInPagePreview );
346             }
347             ++aIter;
348         }
349     }
350 }
351 
352 SwRect SwAccessibleFrame::GetBounds( const SwAccessibleMap& rAccMap,
353                                      const SwFrm *pFrm )
354 {
355     if( !pFrm )
356         pFrm = GetFrm();
357 
358     SwAccessibleChild aFrm( pFrm );
359     SwRect aBounds( aFrm.GetBounds( rAccMap ).Intersection( maVisArea ) );
360     return aBounds;
361 }
362 
363 sal_Bool SwAccessibleFrame::IsEditable( ViewShell *pVSh ) const
364 {
365     const SwFrm *pFrm = GetFrm();
366     if( !pFrm )
367         return sal_False;
368 
369     ASSERT( pVSh, "no view shell" );
370     if( pVSh && (pVSh->GetViewOptions()->IsReadonly() ||
371                  pVSh->IsPreView()) )
372         return sal_False;
373 
374     if( !pFrm->IsRootFrm() && pFrm->IsProtected() )
375         return sal_False;
376 
377     return sal_True;
378 }
379 
380 sal_Bool SwAccessibleFrame::IsOpaque( ViewShell *pVSh ) const
381 {
382     SwAccessibleChild aFrm( GetFrm() );
383     if( !aFrm.GetSwFrm() )
384         return sal_False;
385 
386     ASSERT( pVSh, "no view shell" );
387     if( !pVSh )
388         return sal_False;
389 
390     const SwViewOption *pVOpt = pVSh->GetViewOptions();
391     do
392     {
393         const SwFrm *pFrm = aFrm.GetSwFrm();
394         if( pFrm->IsRootFrm() )
395             return sal_True;
396 
397         if( pFrm->IsPageFrm() && !pVOpt->IsPageBack() )
398             return sal_False;
399 
400         const SvxBrushItem &rBack = pFrm->GetAttrSet()->GetBackground();
401         if( !rBack.GetColor().GetTransparency() ||
402              rBack.GetGraphicPos() != GPOS_NONE )
403             return sal_True;
404 
405         /// OD 20.08.2002 #99657#
406         ///     If a fly frame has a transparent background color, we have
407         ///     to consider the background.
408         ///     But a background color "no fill"/"auto fill" has *not* to be considered.
409         if( pFrm->IsFlyFrm() &&
410             (rBack.GetColor().GetTransparency() != 0) &&
411             (rBack.GetColor() != COL_TRANSPARENT)
412           )
413             return sal_True;
414 
415         if( pFrm->IsSctFrm() )
416         {
417             const SwSection* pSection = ((SwSectionFrm*)pFrm)->GetSection();
418             if( pSection && ( TOX_HEADER_SECTION == pSection->GetType() ||
419                 TOX_CONTENT_SECTION == pSection->GetType() ) &&
420                 !pVOpt->IsReadonly() &&
421                 SwViewOption::IsIndexShadings() )
422                 return sal_True;
423         }
424         if( pFrm->IsFlyFrm() )
425             aFrm = static_cast<const SwFlyFrm*>(pFrm)->GetAnchorFrm();
426         else
427             aFrm = pFrm->GetUpper();
428     } while( aFrm.GetSwFrm() && !aFrm.IsAccessible( IsInPagePreview() ) );
429 
430     return sal_False;
431 }
432 
433 SwAccessibleFrame::SwAccessibleFrame( const SwRect& rVisArea,
434                                       const SwFrm *pF,
435                                       sal_Bool bIsPagePreview ) :
436     maVisArea( rVisArea ),
437     mpFrm( pF ),
438     mbIsInPagePreview( bIsPagePreview ),
439     bIsAccDocUse( sal_False )
440 {
441 }
442 
443 SwAccessibleFrame::~SwAccessibleFrame()
444 {
445 }
446 
447 /* static */ const SwFrm* SwAccessibleFrame::GetParent( const SwAccessibleChild& rFrmOrObj,
448                                                         sal_Bool bInPagePreview )
449 {
450     return rFrmOrObj.GetParent( bInPagePreview );
451 }
452 
453 String SwAccessibleFrame::GetFormattedPageNumber() const
454 {
455     sal_uInt16 nPageNum = GetFrm()->GetVirtPageNum();
456     sal_uInt32 nFmt = GetFrm()->FindPageFrm()->GetPageDesc()
457                               ->GetNumType().GetNumberingType();
458     if( SVX_NUM_NUMBER_NONE == nFmt )
459         nFmt = SVX_NUM_ARABIC;
460 
461     String sRet( FormatNumber( nPageNum, nFmt ) );
462     return sRet;
463 }
464 
465 sal_Int32 SwAccessibleFrame::GetChildCount( SwAccessibleMap& rAccMap ) const
466 {
467     return GetChildCount( rAccMap, maVisArea, mpFrm, IsInPagePreview() );
468 }
469 
470 sw::access::SwAccessibleChild SwAccessibleFrame::GetChild(
471                                                 SwAccessibleMap& rAccMap,
472                                                 sal_Int32 nPos ) const
473 {
474     return SwAccessibleFrame::GetChild( rAccMap, maVisArea, *mpFrm, nPos, IsInPagePreview() );
475 }
476 
477 sal_Int32 SwAccessibleFrame::GetChildIndex( SwAccessibleMap& rAccMap,
478                                             const sw::access::SwAccessibleChild& rChild ) const
479 {
480     sal_Int32 nPos = 0;
481     return GetChildIndex( rAccMap, maVisArea, *mpFrm, rChild, nPos, IsInPagePreview() )
482            ? nPos
483            : -1L;
484 }
485 
486 sw::access::SwAccessibleChild SwAccessibleFrame::GetChildAtPixel(
487                                                 const Point& rPos,
488                                                 SwAccessibleMap& rAccMap ) const
489 {
490     return GetChildAtPixel( maVisArea, *mpFrm, rPos, IsInPagePreview(), rAccMap );
491 }
492 
493 void SwAccessibleFrame::GetChildren( SwAccessibleMap& rAccMap,
494                                      ::std::list< sw::access::SwAccessibleChild >& rChildren ) const
495 {
496     GetChildren( rAccMap, maVisArea, *mpFrm, rChildren, IsInPagePreview() );
497 }
498 
499 sal_Bool SwAccessibleFrame::IsShowing( const SwAccessibleMap& rAccMap,
500                                        const sw::access::SwAccessibleChild& rFrmOrObj ) const
501 {
502     return IsShowing( rFrmOrObj.GetBox( rAccMap ) );
503 }
504 
505