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