xref: /AOO41X/main/sw/source/core/access/accframe.cxx (revision 5ff14ef2c455a7c2a39819566d74aed4bcc9528e)
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