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 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 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 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 //IAccessibility2 Implementation 2009----- 169 // const SwAccessibleChildMap aVisMap( rVisArea, rFrm, rAccMap ); 170 const SwAccessibleChildMap aVisMap( rFrm.PaintArea(), rFrm, rAccMap ); 171 //-----IAccessibility2 Implementation 2009 172 SwAccessibleChildMap::const_iterator aIter( aVisMap.begin() ); 173 while( aIter != aVisMap.end() && !bFound ) 174 { 175 const SwAccessibleChild& rLower = (*aIter).second; 176 if( rLower.IsAccessible( bInPagePreview ) ) 177 { 178 if( rChild == rLower ) 179 bFound = sal_True; 180 else 181 rPos++; 182 } 183 else if( rLower.GetSwFrm() ) 184 { 185 // There are no unaccessible SdrObjects that count 186 bFound = GetChildIndex( rAccMap, 187 rVisArea, *(rLower.GetSwFrm()), rChild, 188 rPos, bInPagePreview ); 189 } 190 ++aIter; 191 } 192 } 193 else 194 { 195 // The unsorted list is sorted enough, because it return lower 196 // frames in the correct order. 197 198 //IAccessibility2 Implementation 2009----- 199 // const SwAccessibleChildSList aVisList( rVisArea, rFrm, rAccMap ); 200 const SwAccessibleChildSList aVisList( rFrm.PaintArea(), rFrm, rAccMap ); 201 //-----IAccessibility2 Implementation 2009 202 203 SwAccessibleChildSList::const_iterator aIter( aVisList.begin() ); 204 while( aIter != aVisList.end() && !bFound ) 205 { 206 const SwAccessibleChild& rLower = *aIter; 207 if( rLower.IsAccessible( bInPagePreview ) ) 208 { 209 if( rChild == rLower ) 210 bFound = sal_True; 211 else 212 rPos++; 213 } 214 else if( rLower.GetSwFrm() ) 215 { 216 // There are no unaccessible SdrObjects that count 217 bFound = GetChildIndex( rAccMap, 218 rVisArea, *(rLower.GetSwFrm()), rChild, 219 rPos, bInPagePreview ); 220 } 221 ++aIter; 222 } 223 } 224 225 return bFound; 226 } 227 228 SwAccessibleChild SwAccessibleFrame::GetChildAtPixel( const SwRect& rVisArea, 229 const SwFrm& rFrm, 230 const Point& rPixPos, 231 sal_Bool bInPagePreview, 232 SwAccessibleMap& rAccMap ) 233 { 234 SwAccessibleChild aRet; 235 236 if( SwAccessibleChildMap::IsSortingRequired( rFrm ) ) 237 { 238 // We need a sorted list here, and we have to reverse iterate, 239 // because objects in front should be returned. 240 const SwAccessibleChildMap aVisMap( rVisArea, rFrm, rAccMap ); 241 SwAccessibleChildMap::const_reverse_iterator aRIter( aVisMap.rbegin() ); 242 while( aRIter != aVisMap.rend() && !aRet.IsValid() ) 243 { 244 const SwAccessibleChild& rLower = (*aRIter).second; 245 // A frame is returned if it's frame size is inside the visarea 246 // and the positiion is inside the frame's paint area. 247 if( rLower.IsAccessible( bInPagePreview ) ) 248 { 249 SwRect aLogBounds( rLower.GetBounds( rAccMap ) ); 250 if( !aLogBounds.IsEmpty() ) 251 { 252 Rectangle aPixBounds( rAccMap.CoreToPixel( aLogBounds.SVRect() ) ); 253 if( aPixBounds.IsInside( rPixPos ) ) 254 aRet = rLower; 255 } 256 } 257 else if( rLower.GetSwFrm() ) 258 { 259 // There are no unaccessible SdrObjects that count 260 aRet = GetChildAtPixel( rVisArea, *(rLower.GetSwFrm()), rPixPos, 261 bInPagePreview, rAccMap ); 262 } 263 aRIter++; 264 } 265 } 266 else 267 { 268 // The unsorted list is sorted enough, because it returns lower 269 // frames in the correct order. Morover, we can iterate forward, 270 // because the lowers don't overlap! 271 const SwAccessibleChildSList aVisList( rVisArea, rFrm, rAccMap ); 272 SwAccessibleChildSList::const_iterator aIter( aVisList.begin() ); 273 while( aIter != aVisList.end() && !aRet.IsValid() ) 274 { 275 const SwAccessibleChild& rLower = *aIter; 276 // A frame is returned if it's frame size is inside the visarea 277 // and the positiion is inside the frame's paint area. 278 if( rLower.IsAccessible( bInPagePreview ) ) 279 { 280 SwRect aLogBounds( rLower.GetBounds( rAccMap ) ); 281 if( !aLogBounds.IsEmpty() ) 282 { 283 Rectangle aPixBounds( rAccMap.CoreToPixel( aLogBounds.SVRect() ) ); 284 if( aPixBounds.IsInside( rPixPos ) ) 285 aRet = rLower; 286 } 287 } 288 else if( rLower.GetSwFrm() ) 289 { 290 // There are no unaccessible SdrObjects that count 291 aRet = GetChildAtPixel( rVisArea, *(rLower.GetSwFrm()), rPixPos, 292 bInPagePreview, rAccMap ); 293 } 294 ++aIter; 295 } 296 } 297 298 return aRet; 299 } 300 301 /* static */ void SwAccessibleFrame::GetChildren( SwAccessibleMap& rAccMap, 302 const SwRect& rVisArea, 303 const SwFrm& rFrm, 304 ::std::list< SwAccessibleChild >& rChildren, 305 sal_Bool bInPagePreview ) 306 { 307 if( SwAccessibleChildMap::IsSortingRequired( rFrm ) ) 308 { 309 // We need a sorted list here 310 const SwAccessibleChildMap aVisMap( rVisArea, rFrm, rAccMap ); 311 SwAccessibleChildMap::const_iterator aIter( aVisMap.begin() ); 312 while( aIter != aVisMap.end() ) 313 { 314 const SwAccessibleChild& rLower = (*aIter).second; 315 if( rLower.IsAccessible( bInPagePreview ) ) 316 { 317 rChildren.push_back( rLower ); 318 } 319 else if( rLower.GetSwFrm() ) 320 { 321 // There are no unaccessible SdrObjects that count 322 GetChildren( rAccMap, rVisArea, *(rLower.GetSwFrm()), 323 rChildren, bInPagePreview ); 324 } 325 ++aIter; 326 } 327 } 328 else 329 { 330 // The unsorted list is sorted enough, because it return lower 331 // frames in the correct order. 332 const SwAccessibleChildSList aVisList( rVisArea, rFrm, rAccMap ); 333 SwAccessibleChildSList::const_iterator aIter( aVisList.begin() ); 334 while( aIter != aVisList.end() ) 335 { 336 const SwAccessibleChild& rLower = *aIter; 337 if( rLower.IsAccessible( bInPagePreview ) ) 338 { 339 rChildren.push_back( rLower ); 340 } 341 else if( rLower.GetSwFrm() ) 342 { 343 // There are no unaccessible SdrObjects that count 344 GetChildren( rAccMap, rVisArea, *(rLower.GetSwFrm()), 345 rChildren, bInPagePreview ); 346 } 347 ++aIter; 348 } 349 } 350 } 351 352 SwRect SwAccessibleFrame::GetBounds( const SwAccessibleMap& rAccMap, 353 const SwFrm *pFrm ) 354 { 355 if( !pFrm ) 356 pFrm = GetFrm(); 357 358 SwAccessibleChild aFrm( pFrm ); 359 SwRect aBounds( aFrm.GetBounds( rAccMap ).Intersection( maVisArea ) ); 360 return aBounds; 361 } 362 363 sal_Bool SwAccessibleFrame::IsEditable( ViewShell *pVSh ) const 364 { 365 const SwFrm *pFrm = GetFrm(); 366 if( !pFrm ) 367 return sal_False; 368 369 ASSERT( pVSh, "no view shell" ); 370 if( pVSh && (pVSh->GetViewOptions()->IsReadonly() || 371 pVSh->IsPreView()) ) 372 return sal_False; 373 374 if( !pFrm->IsRootFrm() && pFrm->IsProtected() ) 375 return sal_False; 376 377 return sal_True; 378 } 379 380 sal_Bool SwAccessibleFrame::IsOpaque( ViewShell *pVSh ) const 381 { 382 SwAccessibleChild aFrm( GetFrm() ); 383 if( !aFrm.GetSwFrm() ) 384 return sal_False; 385 386 ASSERT( pVSh, "no view shell" ); 387 if( !pVSh ) 388 return sal_False; 389 390 const SwViewOption *pVOpt = pVSh->GetViewOptions(); 391 do 392 { 393 const SwFrm *pFrm = aFrm.GetSwFrm(); 394 if( pFrm->IsRootFrm() ) 395 return sal_True; 396 397 if( pFrm->IsPageFrm() && !pVOpt->IsPageBack() ) 398 return sal_False; 399 400 const SvxBrushItem &rBack = pFrm->GetAttrSet()->GetBackground(); 401 if( !rBack.GetColor().GetTransparency() || 402 rBack.GetGraphicPos() != GPOS_NONE ) 403 return sal_True; 404 405 /// OD 20.08.2002 #99657# 406 /// If a fly frame has a transparent background color, we have 407 /// to consider the background. 408 /// But a background color "no fill"/"auto fill" has *not* to be considered. 409 if( pFrm->IsFlyFrm() && 410 (rBack.GetColor().GetTransparency() != 0) && 411 (rBack.GetColor() != COL_TRANSPARENT) 412 ) 413 return sal_True; 414 415 if( pFrm->IsSctFrm() ) 416 { 417 const SwSection* pSection = ((SwSectionFrm*)pFrm)->GetSection(); 418 if( pSection && ( TOX_HEADER_SECTION == pSection->GetType() || 419 TOX_CONTENT_SECTION == pSection->GetType() ) && 420 !pVOpt->IsReadonly() && 421 SwViewOption::IsIndexShadings() ) 422 return sal_True; 423 } 424 if( pFrm->IsFlyFrm() ) 425 aFrm = static_cast<const SwFlyFrm*>(pFrm)->GetAnchorFrm(); 426 else 427 aFrm = pFrm->GetUpper(); 428 } while( aFrm.GetSwFrm() && !aFrm.IsAccessible( IsInPagePreview() ) ); 429 430 return sal_False; 431 } 432 433 SwAccessibleFrame::SwAccessibleFrame( const SwRect& rVisArea, 434 const SwFrm *pF, 435 sal_Bool bIsPagePreview ) : 436 maVisArea( rVisArea ), 437 mpFrm( pF ), 438 mbIsInPagePreview( bIsPagePreview ), 439 bIsAccDocUse( sal_False ) 440 { 441 } 442 443 SwAccessibleFrame::~SwAccessibleFrame() 444 { 445 } 446 447 /* static */ const SwFrm* SwAccessibleFrame::GetParent( const SwAccessibleChild& rFrmOrObj, 448 sal_Bool bInPagePreview ) 449 { 450 return rFrmOrObj.GetParent( bInPagePreview ); 451 } 452 453 String SwAccessibleFrame::GetFormattedPageNumber() const 454 { 455 sal_uInt16 nPageNum = GetFrm()->GetVirtPageNum(); 456 sal_uInt32 nFmt = GetFrm()->FindPageFrm()->GetPageDesc() 457 ->GetNumType().GetNumberingType(); 458 if( SVX_NUM_NUMBER_NONE == nFmt ) 459 nFmt = SVX_NUM_ARABIC; 460 461 String sRet( FormatNumber( nPageNum, nFmt ) ); 462 return sRet; 463 } 464 465 sal_Int32 SwAccessibleFrame::GetChildCount( SwAccessibleMap& rAccMap ) const 466 { 467 return GetChildCount( rAccMap, maVisArea, mpFrm, IsInPagePreview() ); 468 } 469 470 sw::access::SwAccessibleChild SwAccessibleFrame::GetChild( 471 SwAccessibleMap& rAccMap, 472 sal_Int32 nPos ) const 473 { 474 return SwAccessibleFrame::GetChild( rAccMap, maVisArea, *mpFrm, nPos, IsInPagePreview() ); 475 } 476 477 sal_Int32 SwAccessibleFrame::GetChildIndex( SwAccessibleMap& rAccMap, 478 const sw::access::SwAccessibleChild& rChild ) const 479 { 480 sal_Int32 nPos = 0; 481 return GetChildIndex( rAccMap, maVisArea, *mpFrm, rChild, nPos, IsInPagePreview() ) 482 ? nPos 483 : -1L; 484 } 485 486 sw::access::SwAccessibleChild SwAccessibleFrame::GetChildAtPixel( 487 const Point& rPos, 488 SwAccessibleMap& rAccMap ) const 489 { 490 return GetChildAtPixel( maVisArea, *mpFrm, rPos, IsInPagePreview(), rAccMap ); 491 } 492 493 void SwAccessibleFrame::GetChildren( SwAccessibleMap& rAccMap, 494 ::std::list< sw::access::SwAccessibleChild >& rChildren ) const 495 { 496 GetChildren( rAccMap, maVisArea, *mpFrm, rChildren, IsInPagePreview() ); 497 } 498 499 sal_Bool SwAccessibleFrame::IsShowing( const SwAccessibleMap& rAccMap, 500 const sw::access::SwAccessibleChild& rFrmOrObj ) const 501 { 502 return IsShowing( rFrmOrObj.GetBox( rAccMap ) ); 503 } 504 505