xref: /trunk/main/sw/source/core/access/accframe.cxx (revision 4d7c9de0)
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