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 // 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 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 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 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 359 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 376 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 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 439 SwAccessibleFrame::~SwAccessibleFrame() 440 { 441 } 442 443 /* static */ const SwFrm* SwAccessibleFrame::GetParent( const SwAccessibleChild& rFrmOrObj, 444 sal_Bool bInPagePreview ) 445 { 446 return rFrmOrObj.GetParent( bInPagePreview ); 447 } 448 449 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 461 sal_Int32 SwAccessibleFrame::GetChildCount( SwAccessibleMap& rAccMap ) const 462 { 463 return GetChildCount( rAccMap, maVisArea, mpFrm, IsInPagePreview() ); 464 } 465 466 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 473 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 482 sw::access::SwAccessibleChild SwAccessibleFrame::GetChildAtPixel( 483 const Point& rPos, 484 SwAccessibleMap& rAccMap ) const 485 { 486 return GetChildAtPixel( maVisArea, *mpFrm, rPos, IsInPagePreview(), rAccMap ); 487 } 488 489 void SwAccessibleFrame::GetChildren( SwAccessibleMap& rAccMap, 490 ::std::list< sw::access::SwAccessibleChild >& rChildren ) const 491 { 492 GetChildren( rAccMap, maVisArea, *mpFrm, rChildren, IsInPagePreview() ); 493 } 494 495 sal_Bool SwAccessibleFrame::IsShowing( const SwAccessibleMap& rAccMap, 496 const sw::access::SwAccessibleChild& rFrmOrObj ) const 497 { 498 return IsShowing( rFrmOrObj.GetBox( rAccMap ) ); 499 } 500 501