Update ooo320-m1
[ooovba.git] / sw / source / core / access / accframe.cxx
blobce6c2ad0e144e08988661bdb2f71138fb1e0ede9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: accframe.cxx,v $
10 * $Revision: 1.26 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
36 #include <hintids.hxx>
37 #include <svx/brshitem.hxx>
38 #include <flyfrm.hxx>
39 #include <rootfrm.hxx>
40 #include <txtfrm.hxx>
41 #include <sectfrm.hxx>
42 #include <pagefrm.hxx>
43 #include <section.hxx>
44 #include <viewsh.hxx>
45 #include <viewopt.hxx>
46 #include <doc.hxx>
47 #include <frmatr.hxx>
48 #include <pagefrm.hxx>
49 #include <pagedesc.hxx>
50 #include <fmtanchr.hxx>
51 #include <fldbas.hxx>
52 #include <dcontact.hxx>
53 #include <accmap.hxx>
54 #include <accfrmobjslist.hxx>
55 #include <accfrmobjmap.hxx>
56 #include <accframe.hxx>
59 // Regarding visibilily (or in terms of accessibility: regarding the showing
60 // state): A frame is visible and therfor contained in the tree if its frame
61 // size overlaps with the visible area. The bounding box however is the
62 // frame's paint area.
63 sal_Int32 SwAccessibleFrame::GetChildCount( const SwRect& rVisArea,
64 const SwFrm *pFrm,
65 sal_Bool bInPagePreview )
67 sal_Int32 nCount = 0;
69 const SwFrmOrObjSList aVisList( rVisArea, pFrm );
70 SwFrmOrObjSList::const_iterator aIter( aVisList.begin() );
71 while( aIter != aVisList.end() )
73 const SwFrmOrObj& rLower = *aIter;
74 if( rLower.IsAccessible( bInPagePreview ) )
76 nCount++;
78 else if( rLower.GetSwFrm() )
80 // There are no unaccessible SdrObjects that count
81 nCount += GetChildCount( rVisArea, rLower.GetSwFrm(),
82 bInPagePreview );
84 ++aIter;
87 return nCount;
90 SwFrmOrObj SwAccessibleFrame::GetChild( const SwRect& rVisArea,
91 const SwFrm *pFrm,
92 sal_Int32& rPos,
93 sal_Bool bInPagePreview )
95 SwFrmOrObj aRet;
97 if( rPos >= 0 )
99 if( SwFrmOrObjMap::IsSortingRequired( pFrm ) )
101 // We need a sorted list here
102 const SwFrmOrObjMap aVisMap( rVisArea, pFrm );
103 SwFrmOrObjMap::const_iterator aIter( aVisMap.begin() );
104 while( aIter != aVisMap.end() && !aRet.IsValid() )
106 const SwFrmOrObj& rLower = (*aIter).second;
107 if( rLower.IsAccessible( bInPagePreview ) )
109 if( 0 == rPos )
110 aRet = rLower;
111 else
112 rPos--;
114 else if( rLower.GetSwFrm() )
116 // There are no unaccessible SdrObjects that count
117 aRet = GetChild( rVisArea, rLower.GetSwFrm(), rPos,
118 bInPagePreview );
120 ++aIter;
123 else
125 // The unsorted list is sorted enough, because it return lower
126 // frames in the correct order.
127 const SwFrmOrObjSList aVisList( rVisArea, pFrm );
128 SwFrmOrObjSList::const_iterator aIter( aVisList.begin() );
129 while( aIter != aVisList.end() && !aRet.IsValid() )
131 const SwFrmOrObj& rLower = *aIter;
132 if( rLower.IsAccessible( bInPagePreview ) )
134 if( 0 == rPos )
135 aRet = rLower;
136 else
137 rPos--;
139 else if( rLower.GetSwFrm() )
141 // There are no unaccessible SdrObjects that count
142 aRet = GetChild( rVisArea, rLower.GetSwFrm(), rPos,
143 bInPagePreview );
145 ++aIter;
150 return aRet;
153 sal_Bool SwAccessibleFrame::GetChildIndex( const SwRect& rVisArea,
154 const SwFrm *pFrm,
155 const SwFrmOrObj& rChild,
156 sal_Int32& rPos,
157 sal_Bool bInPagePreview )
159 sal_Bool bFound = sal_False;
161 if( SwFrmOrObjMap::IsSortingRequired( pFrm ) )
163 // We need a sorted list here
164 const SwFrmOrObjMap aVisMap( rVisArea, pFrm );
165 SwFrmOrObjMap::const_iterator aIter( aVisMap.begin() );
166 while( aIter != aVisMap.end() && !bFound )
168 const SwFrmOrObj& rLower = (*aIter).second;
169 if( rLower.IsAccessible( bInPagePreview ) )
171 if( rChild == rLower )
172 bFound = sal_True;
173 else
174 rPos++;
176 else if( rLower.GetSwFrm() )
178 // There are no unaccessible SdrObjects that count
179 bFound = GetChildIndex( rVisArea, rLower.GetSwFrm(), rChild,
180 rPos, bInPagePreview );
182 ++aIter;
185 else
187 // The unsorted list is sorted enough, because it return lower
188 // frames in the correct order.
189 const SwFrmOrObjSList aVisList( rVisArea, pFrm );
190 SwFrmOrObjSList::const_iterator aIter( aVisList.begin() );
191 while( aIter != aVisList.end() && !bFound )
193 const SwFrmOrObj& rLower = *aIter;
194 if( rLower.IsAccessible( bInPagePreview ) )
196 if( rChild == rLower )
197 bFound = sal_True;
198 else
199 rPos++;
201 else if( rLower.GetSwFrm() )
203 // There are no unaccessible SdrObjects that count
204 bFound = GetChildIndex( rVisArea, rLower.GetSwFrm(), rChild,
205 rPos, bInPagePreview );
207 ++aIter;
211 return bFound;
214 SwFrmOrObj SwAccessibleFrame::GetChildAtPixel( const SwRect& rVisArea,
215 const SwFrm *pFrm,
216 const Point& rPixPos,
217 sal_Bool bInPagePreview,
218 const SwAccessibleMap *pMap )
220 SwFrmOrObj aRet;
222 if( SwFrmOrObjMap::IsSortingRequired( pFrm ) )
224 // We need a sorted list here, and we have to reverse iterate,
225 // because objects in front should be returned.
226 const SwFrmOrObjMap aVisMap( rVisArea, pFrm );
227 SwFrmOrObjMap::const_reverse_iterator aRIter( aVisMap.rbegin() );
228 while( aRIter != aVisMap.rend() && !aRet.IsValid() )
230 const SwFrmOrObj& rLower = (*aRIter).second;
231 // A frame is returned if it's frame size is inside the visarea
232 // and the positiion is inside the frame's paint area.
233 if( rLower.IsAccessible( bInPagePreview ) )
235 SwRect aLogBounds( rLower.GetBounds( ) );
236 if( !aLogBounds.IsEmpty() )
238 Rectangle aPixBounds( pMap->CoreToPixel( aLogBounds.SVRect() ) );
239 if( aPixBounds.IsInside( rPixPos ) )
240 aRet = rLower;
243 else if( rLower.GetSwFrm() )
245 // There are no unaccessible SdrObjects that count
246 aRet = GetChildAtPixel( rVisArea, rLower.GetSwFrm(), rPixPos,
247 bInPagePreview, pMap );
249 aRIter++;
252 else
254 // The unsorted list is sorted enough, because it returns lower
255 // frames in the correct order. Morover, we can iterate forward,
256 // because the lowers don't overlap!
257 const SwFrmOrObjSList aVisList( rVisArea, pFrm );
258 SwFrmOrObjSList::const_iterator aIter( aVisList.begin() );
259 while( aIter != aVisList.end() && !aRet.IsValid() )
261 const SwFrmOrObj& rLower = *aIter;
262 // A frame is returned if it's frame size is inside the visarea
263 // and the positiion is inside the frame's paint area.
264 if( rLower.IsAccessible( bInPagePreview ) )
266 SwRect aLogBounds( rLower.GetBounds( ) );
267 if( !aLogBounds.IsEmpty() )
269 Rectangle aPixBounds( pMap->CoreToPixel( aLogBounds.SVRect() ) );
270 if( aPixBounds.IsInside( rPixPos ) )
271 aRet = rLower;
274 else if( rLower.GetSwFrm() )
276 // There are no unaccessible SdrObjects that count
277 aRet = GetChildAtPixel( rVisArea, rLower.GetSwFrm(), rPixPos,
278 bInPagePreview, pMap );
280 ++aIter;
284 return aRet;
287 void SwAccessibleFrame::GetChildren( const SwRect& rVisArea, const SwFrm *pFrm,
288 ::std::list< SwFrmOrObj >& rChildren,
289 sal_Bool bInPagePreview )
291 if( SwFrmOrObjMap::IsSortingRequired( pFrm ) )
293 // We need a sorted list here
294 const SwFrmOrObjMap aVisMap( rVisArea, pFrm );
295 SwFrmOrObjMap::const_iterator aIter( aVisMap.begin() );
296 while( aIter != aVisMap.end() )
298 const SwFrmOrObj& rLower = (*aIter).second;
299 if( rLower.IsAccessible( bInPagePreview ) )
301 rChildren.push_back( rLower );
303 else if( rLower.GetSwFrm() )
305 // There are no unaccessible SdrObjects that count
306 GetChildren( rVisArea, rLower.GetSwFrm(), rChildren,
307 bInPagePreview );
309 ++aIter;
312 else
314 // The unsorted list is sorted enough, because it return lower
315 // frames in the correct order.
316 const SwFrmOrObjSList aVisList( rVisArea, pFrm );
317 SwFrmOrObjSList::const_iterator aIter( aVisList.begin() );
318 while( aIter != aVisList.end() )
320 const SwFrmOrObj& rLower = *aIter;
321 if( rLower.IsAccessible( bInPagePreview ) )
323 rChildren.push_back( rLower );
325 else if( rLower.GetSwFrm() )
327 // There are no unaccessible SdrObjects that count
328 GetChildren( rVisArea, rLower.GetSwFrm(), rChildren,
329 bInPagePreview );
331 ++aIter;
336 SwRect SwAccessibleFrame::GetBounds( const SwFrm *pFrm )
338 if( !pFrm )
339 pFrm = GetFrm();
341 SwFrmOrObj aFrm( pFrm );
342 SwRect aBounds( aFrm.GetBounds().Intersection( maVisArea ) );
343 return aBounds;
346 sal_Bool SwAccessibleFrame::IsEditable( ViewShell *pVSh ) const
348 const SwFrm *pFrm = GetFrm();
349 if( !pFrm )
350 return sal_False;
352 ASSERT( pVSh, "no view shell" );
353 if( pVSh && (pVSh->GetViewOptions()->IsReadonly() ||
354 pVSh->IsPreView()) )
355 return sal_False;
357 if( !pFrm->IsRootFrm() && pFrm->IsProtected() )
358 return sal_False;
360 return sal_True;
363 sal_Bool SwAccessibleFrame::IsOpaque( ViewShell *pVSh ) const
365 SwFrmOrObj aFrm( GetFrm() );
366 if( !aFrm.GetSwFrm() )
367 return sal_False;
369 ASSERT( pVSh, "no view shell" );
370 if( !pVSh )
371 return sal_False;
373 const SwViewOption *pVOpt = pVSh->GetViewOptions();
376 const SwFrm *pFrm = aFrm.GetSwFrm();
377 if( pFrm->IsRootFrm() )
378 return sal_True;
380 if( pFrm->IsPageFrm() && !pVOpt->IsPageBack() )
381 return sal_False;
383 const SvxBrushItem &rBack = pFrm->GetAttrSet()->GetBackground();
384 if( !rBack.GetColor().GetTransparency() ||
385 rBack.GetGraphicPos() != GPOS_NONE )
386 return sal_True;
388 /// OD 20.08.2002 #99657#
389 /// If a fly frame has a transparent background color, we have
390 /// to consider the background.
391 /// But a background color "no fill"/"auto fill" has *not* to be considered.
392 if( pFrm->IsFlyFrm() &&
393 (rBack.GetColor().GetTransparency() != 0) &&
394 (rBack.GetColor() != COL_TRANSPARENT)
396 return sal_True;
398 if( pFrm->IsSctFrm() )
400 const SwSection* pSection = ((SwSectionFrm*)pFrm)->GetSection();
401 if( pSection && ( TOX_HEADER_SECTION == pSection->GetType() ||
402 TOX_CONTENT_SECTION == pSection->GetType() ) &&
403 !pVOpt->IsReadonly() &&
404 SwViewOption::IsIndexShadings() )
405 return sal_True;
407 if( pFrm->IsFlyFrm() )
408 aFrm = static_cast<const SwFlyFrm*>(pFrm)->GetAnchorFrm();
409 else
410 aFrm = pFrm->GetUpper();
411 } while( aFrm.GetSwFrm() && !aFrm.IsAccessible( IsInPagePreview() ) );
413 return sal_False;
416 SwAccessibleFrame::SwAccessibleFrame( const SwRect& rVisArea,
417 const SwFrm *pF,
418 sal_Bool bIsPagePreview ) :
419 maVisArea( rVisArea ),
420 mpFrm( pF ),
421 mbIsInPagePreview( bIsPagePreview )
425 SwAccessibleFrame::~SwAccessibleFrame()
429 const SwFrm *SwAccessibleFrame::GetParent( const SwFrmOrObj& rFrmOrObj,
430 sal_Bool bInPagePreview )
432 SwFrmOrObj aParent;
433 const SwFrm *pFrm = rFrmOrObj.GetSwFrm();
434 if( pFrm )
436 if( pFrm->IsFlyFrm() )
438 const SwFlyFrm *pFly = static_cast< const SwFlyFrm *>( pFrm );
439 if( pFly->IsFlyInCntFrm() )
441 // For FLY_IN_CNTNT the parent is the anchor
442 aParent = pFly->GetAnchorFrm();
443 ASSERT( aParent.IsAccessible( bInPagePreview ),
444 "parent is not accessible" );
446 else
448 // In any other case the parent is the root frm
449 // (in page preview, the page frame)
450 if( bInPagePreview )
451 aParent = pFly->FindPageFrm();
452 else
453 aParent = pFly->FindRootFrm();
456 else
458 SwFrmOrObj aUpper( pFrm->GetUpper() );
459 while( aUpper.GetSwFrm() && !aUpper.IsAccessible(bInPagePreview) )
460 aUpper = aUpper.GetSwFrm()->GetUpper();
461 aParent = aUpper;
464 else if( rFrmOrObj.GetSdrObject() )
466 const SwDrawContact *pContact =
467 static_cast< const SwDrawContact* >(
468 GetUserCall( rFrmOrObj.GetSdrObject() ) );
469 ASSERT( pContact, "sdr contact is missing" );
470 if( pContact )
472 const SwFrmFmt *pFrmFmt = pContact->GetFmt();
473 ASSERT( pFrmFmt, "frame format is missing" );
474 if( pFrmFmt && FLY_IN_CNTNT == pFrmFmt->GetAnchor().GetAnchorId() )
476 // For FLY_IN_CNTNT the parent is the anchor
477 aParent = pContact->GetAnchorFrm();
478 ASSERT( aParent.IsAccessible( bInPagePreview ),
479 "parent is not accessible" );
482 else
484 // In any other case the parent is the root frm
485 if( bInPagePreview )
486 aParent = pContact->GetAnchorFrm()->FindPageFrm();
487 else
488 aParent = pContact->GetAnchorFrm()->FindRootFrm();
493 return aParent.GetSwFrm();
496 String SwAccessibleFrame::GetFormattedPageNumber() const
498 sal_uInt16 nPageNum = GetFrm()->GetVirtPageNum();
499 sal_uInt32 nFmt = GetFrm()->FindPageFrm()->GetPageDesc()
500 ->GetNumType().GetNumberingType();
501 if( SVX_NUM_NUMBER_NONE == nFmt )
502 nFmt = SVX_NUM_ARABIC;
504 String sRet( FormatNumber( nPageNum, nFmt ) );
505 return sRet;