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