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