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