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