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