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 #include <accfrmobj.hxx> 28 29 #include <accmap.hxx> 30 #include <acccontext.hxx> 31 32 #include <viewsh.hxx> 33 #include <rootfrm.hxx> 34 #include <flyfrm.hxx> 35 #include <pagefrm.hxx> 36 #include <cellfrm.hxx> 37 #include <swtable.hxx> 38 #include <dflyobj.hxx> 39 #include <frmfmt.hxx> 40 #include <fmtanchr.hxx> 41 #include <dcontact.hxx> 42 43 #include <pam.hxx> 44 45 #include <vcl/window.hxx> 46 47 namespace css = ::com::sun::star; 48 49 namespace sw { namespace access { 50 51 SwAccessibleChild::SwAccessibleChild() 52 : mpFrm( 0 ) 53 , mpDrawObj( 0 ) 54 , mpWindow( 0 ) 55 {} 56 57 SwAccessibleChild::SwAccessibleChild( const SdrObject* pDrawObj ) 58 : mpFrm( 0 ) 59 , mpDrawObj( 0 ) 60 , mpWindow( 0 ) 61 { 62 Init( pDrawObj ); 63 } 64 65 SwAccessibleChild::SwAccessibleChild( const SwFrm* pFrm ) 66 : mpFrm( 0 ) 67 , mpDrawObj( 0 ) 68 , mpWindow( 0 ) 69 { 70 Init( pFrm ); 71 } 72 73 SwAccessibleChild::SwAccessibleChild( Window* pWindow ) 74 : mpFrm( 0 ) 75 , mpDrawObj( 0 ) 76 , mpWindow( 0 ) 77 { 78 Init( pWindow ); 79 } 80 81 82 SwAccessibleChild::SwAccessibleChild( const SwFrm* pFrm, 83 const SdrObject* pDrawObj, 84 Window* pWindow ) 85 { 86 if ( pFrm ) 87 { 88 Init( pFrm ); 89 } 90 else if ( pDrawObj ) 91 { 92 Init( pDrawObj ); 93 } 94 else if ( pWindow ) 95 { 96 Init( pWindow ); 97 } 98 ASSERT( (!pFrm || pFrm == mpFrm) && 99 (!pDrawObj || pDrawObj == mpDrawObj) && 100 (!pWindow || pWindow == mpWindow), 101 "invalid frame/object/window combination" ); 102 103 } 104 105 void SwAccessibleChild::Init( const SdrObject* pDrawObj ) 106 { 107 mpDrawObj = pDrawObj; 108 mpFrm = mpDrawObj && mpDrawObj->ISA(SwVirtFlyDrawObj) 109 ? static_cast < const SwVirtFlyDrawObj * >( mpDrawObj )->GetFlyFrm() 110 : 0; 111 mpWindow = 0; 112 } 113 114 void SwAccessibleChild::Init( const SwFrm* pFrm ) 115 { 116 mpFrm = pFrm; 117 mpDrawObj = mpFrm && mpFrm->IsFlyFrm() 118 ? static_cast < const SwFlyFrm * >( mpFrm )->GetVirtDrawObj() 119 : 0; 120 mpWindow = 0; 121 } 122 123 void SwAccessibleChild::Init( Window* pWindow ) 124 { 125 mpWindow = pWindow; 126 mpFrm = 0; 127 mpDrawObj = 0; 128 } 129 130 bool SwAccessibleChild::IsAccessible( sal_Bool bPagePreview ) const 131 { 132 bool bRet( false ); 133 134 if ( mpFrm ) 135 { 136 bRet = mpFrm->IsAccessibleFrm() && 137 ( !mpFrm->IsCellFrm() || 138 static_cast<const SwCellFrm *>( mpFrm )->GetTabBox()->GetSttNd() != 0 ) && 139 !mpFrm->IsInCoveredCell() && 140 ( bPagePreview || 141 !mpFrm->IsPageFrm() ); 142 } 143 else if ( mpDrawObj ) 144 { 145 bRet = true; 146 } 147 else if ( mpWindow ) 148 { 149 bRet = true; 150 } 151 152 return bRet; 153 } 154 155 bool SwAccessibleChild::IsBoundAsChar() const 156 { 157 bool bRet( false ); 158 159 if ( mpFrm ) 160 { 161 bRet = mpFrm->IsFlyFrm() && 162 static_cast< const SwFlyFrm *>(mpFrm)->IsFlyInCntFrm(); 163 } 164 else if ( mpDrawObj ) 165 { 166 const SwFrmFmt* mpFrmFmt = ::FindFrmFmt( mpDrawObj ); 167 bRet = mpFrmFmt 168 ? (FLY_AS_CHAR == mpFrmFmt->GetAnchor().GetAnchorId()) 169 : false; 170 } 171 else if ( mpWindow ) 172 { 173 bRet = false; 174 } 175 176 return bRet; 177 } 178 179 sal_uInt32 SwAccessibleChild::GetAnchorPosition() const 180 { 181 if( mpDrawObj ) 182 { 183 const SwFrmFmt *pFrmFmt = ::FindFrmFmt( mpDrawObj ); 184 if ( pFrmFmt ) 185 { 186 const SwPosition *pPos = pFrmFmt->GetAnchor().GetCntntAnchor(); 187 if ( pPos ) 188 { 189 return pPos->nContent.GetIndex(); 190 } 191 } 192 } 193 return 0; 194 } 195 196 SwAccessibleChild::SwAccessibleChild( const SwAccessibleChild& r ) 197 : mpFrm( r.mpFrm ) 198 , mpDrawObj( r.mpDrawObj ) 199 , mpWindow( r.mpWindow ) 200 {} 201 202 SwAccessibleChild& SwAccessibleChild::operator=( const SwAccessibleChild& r ) 203 { 204 mpDrawObj = r.mpDrawObj; 205 mpFrm = r.mpFrm; 206 mpWindow = r.mpWindow; 207 208 return *this; 209 } 210 211 SwAccessibleChild& SwAccessibleChild::operator=( const SdrObject* pDrawObj ) 212 { 213 Init( pDrawObj ); 214 return *this; 215 } 216 217 SwAccessibleChild& SwAccessibleChild::operator=( const SwFrm* pFrm ) 218 { 219 Init( pFrm ); 220 return *this; 221 } 222 223 SwAccessibleChild& SwAccessibleChild::operator=( Window* pWindow ) 224 { 225 Init( pWindow ); 226 return *this; 227 } 228 229 bool SwAccessibleChild::operator==( const SwAccessibleChild& r ) const 230 { 231 return mpFrm == r.mpFrm && 232 mpDrawObj == r.mpDrawObj && 233 mpWindow == r.mpWindow; 234 } 235 236 bool SwAccessibleChild::IsValid() const 237 { 238 return mpFrm != 0 || 239 mpDrawObj != 0 || 240 mpWindow != 0; 241 } 242 243 const SdrObject* SwAccessibleChild::GetDrawObject() const 244 { 245 return mpDrawObj; 246 } 247 248 const SwFrm *SwAccessibleChild::GetSwFrm() const 249 { 250 return mpFrm; 251 } 252 253 Window* SwAccessibleChild::GetWindow() const 254 { 255 return mpWindow; 256 } 257 258 bool SwAccessibleChild::IsVisibleChildrenOnly() const 259 { 260 bool bRet( false ); 261 262 if ( !mpFrm ) 263 { 264 bRet = true; 265 } 266 else 267 { 268 bRet = mpFrm->IsRootFrm() || 269 !( mpFrm->IsTabFrm() || 270 mpFrm->IsInTab() || 271 ( IsBoundAsChar() && 272 static_cast<const SwFlyFrm*>(mpFrm)->GetAnchorFrm()->IsInTab() ) ); 273 } 274 275 return bRet; 276 } 277 278 SwRect SwAccessibleChild::GetBox( const SwAccessibleMap& rAccMap ) const 279 { 280 SwRect aBox; 281 282 if ( mpFrm ) 283 { 284 if ( mpFrm->IsPageFrm() && 285 static_cast< const SwPageFrm * >( mpFrm )->IsEmptyPage() ) 286 { 287 aBox = SwRect( mpFrm->Frm().Left(), mpFrm->Frm().Top()-1, 1, 1 ); 288 } 289 else if ( mpFrm->IsTabFrm() ) 290 { 291 aBox = SwRect( mpFrm->Frm() ); 292 aBox.Intersection( mpFrm->GetUpper()->Frm() ); 293 } 294 else 295 { 296 aBox = mpFrm->Frm(); 297 } 298 } 299 else if( mpDrawObj ) 300 { 301 aBox = SwRect( mpDrawObj->GetCurrentBoundRect() ); 302 } 303 else if ( mpWindow ) 304 { 305 aBox = SwRect( rAccMap.GetShell()->GetWin()->PixelToLogic( 306 Rectangle( mpWindow->GetPosPixel(), 307 mpWindow->GetSizePixel() ) ) ); 308 } 309 310 return aBox; 311 } 312 313 SwRect SwAccessibleChild::GetBounds( const SwAccessibleMap& rAccMap ) const 314 { 315 SwRect aBound; 316 317 if( mpFrm ) 318 { 319 if( mpFrm->IsPageFrm() && 320 static_cast< const SwPageFrm * >( mpFrm )->IsEmptyPage() ) 321 { 322 aBound = SwRect( mpFrm->Frm().Left(), mpFrm->Frm().Top()-1, 0, 0 ); 323 } 324 else 325 aBound = mpFrm->PaintArea(); 326 } 327 else if( mpDrawObj ) 328 { 329 aBound = GetBox( rAccMap ); 330 } 331 else if ( mpWindow ) 332 { 333 aBound = GetBox( rAccMap ); 334 } 335 336 return aBound; 337 } 338 339 bool SwAccessibleChild::AlwaysIncludeAsChild() const 340 { 341 bool bAlwaysIncludedAsChild( false ); 342 343 if ( mpWindow ) 344 { 345 bAlwaysIncludedAsChild = true; 346 } 347 348 return bAlwaysIncludedAsChild; 349 } 350 351 const SwFrm* SwAccessibleChild::GetParent( const sal_Bool bInPagePreview ) const 352 { 353 const SwFrm* pParent( 0 ); 354 355 if ( mpFrm ) 356 { 357 if( mpFrm->IsFlyFrm() ) 358 { 359 const SwFlyFrm* pFly = static_cast< const SwFlyFrm *>( mpFrm ); 360 if( pFly->IsFlyInCntFrm() ) 361 { 362 // For FLY_AS_CHAR the parent is the anchor 363 pParent = pFly->GetAnchorFrm(); 364 ASSERT( SwAccessibleChild( pParent ).IsAccessible( bInPagePreview ), 365 "parent is not accessible" ); 366 } 367 else 368 { 369 // In any other case the parent is the root frm 370 // (in page preview, the page frame) 371 if( bInPagePreview ) 372 pParent = pFly->FindPageFrm(); 373 else 374 pParent = pFly->getRootFrm(); 375 } 376 } 377 else 378 { 379 SwAccessibleChild aUpper( mpFrm->GetUpper() ); 380 while( aUpper.GetSwFrm() && !aUpper.IsAccessible(bInPagePreview) ) 381 { 382 aUpper = aUpper.GetSwFrm()->GetUpper(); 383 } 384 pParent = aUpper.GetSwFrm(); 385 } 386 } 387 else if( mpDrawObj ) 388 { 389 const SwDrawContact *pContact = 390 static_cast< const SwDrawContact* >( GetUserCall( mpDrawObj ) ); 391 ASSERT( pContact, "sdr contact is missing" ); 392 if( pContact ) 393 { 394 const SwFrmFmt *pFrmFmt = pContact->GetFmt(); 395 ASSERT( pFrmFmt, "frame format is missing" ); 396 if( pFrmFmt && FLY_AS_CHAR == pFrmFmt->GetAnchor().GetAnchorId() ) 397 { 398 // For FLY_AS_CHAR the parent is the anchor 399 pParent = pContact->GetAnchorFrm(); 400 ASSERT( SwAccessibleChild( pParent ).IsAccessible( bInPagePreview ), 401 "parent is not accessible" ); 402 403 } 404 else 405 { 406 // In any other case the parent is the root frm 407 if( bInPagePreview ) 408 pParent = pContact->GetAnchorFrm()->FindPageFrm(); 409 else 410 pParent = pContact->GetAnchorFrm()->getRootFrm(); 411 } 412 } 413 } 414 else if ( mpWindow ) 415 { 416 css::uno::Reference < css::accessibility::XAccessible > xAcc = 417 mpWindow->GetAccessible(); 418 if ( xAcc.is() ) 419 { 420 css::uno::Reference < css::accessibility::XAccessibleContext > xAccContext = 421 xAcc->getAccessibleContext(); 422 if ( xAccContext.is() ) 423 { 424 css::uno::Reference < css::accessibility::XAccessible > xAccParent = 425 xAccContext->getAccessibleParent(); 426 if ( xAccParent.is() ) 427 { 428 SwAccessibleContext* pAccParentImpl = 429 dynamic_cast< SwAccessibleContext *>( xAccParent.get() ); 430 if ( pAccParentImpl ) 431 { 432 pParent = pAccParentImpl->GetFrm(); 433 } 434 } 435 } 436 } 437 } 438 439 return pParent; 440 } 441 442 } } // eof of namespace sw::access 443 444