1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "accfrmobj.hxx"
23 #include "acccontext.hxx"
26 #include <rootfrm.hxx>
28 #include <pagefrm.hxx>
29 #include <cellfrm.hxx>
30 #include <swtable.hxx>
31 #include <dflyobj.hxx>
33 #include <fmtanchr.hxx>
34 #include <dcontact.hxx>
36 #include <vcl/window.hxx>
38 namespace sw::access
{
40 SwAccessibleChild::SwAccessibleChild()
42 , mpDrawObj( nullptr )
46 SwAccessibleChild::SwAccessibleChild( const SdrObject
* pDrawObj
)
48 , mpDrawObj( nullptr )
54 SwAccessibleChild::SwAccessibleChild( const SwFrame
* pFrame
)
56 , mpDrawObj( nullptr )
62 SwAccessibleChild::SwAccessibleChild( vcl::Window
* pWindow
)
64 , mpDrawObj( nullptr )
70 SwAccessibleChild::SwAccessibleChild( const SwFrame
* pFrame
,
71 const SdrObject
* pDrawObj
,
72 vcl::Window
* pWindow
)
74 , mpDrawObj( nullptr )
89 OSL_ENSURE( (!pFrame
|| pFrame
== mpFrame
) &&
90 (!pDrawObj
|| pDrawObj
== mpDrawObj
) &&
91 (!pWindow
|| pWindow
== mpWindow
),
92 "invalid frame/object/window combination" );
96 SwAccessibleChild::~SwAccessibleChild() = default;
98 void SwAccessibleChild::Init( const SdrObject
* pDrawObj
)
100 mpDrawObj
= pDrawObj
;
101 const SwVirtFlyDrawObj
* pFlyDrawObj
= dynamic_cast<const SwVirtFlyDrawObj
*>(mpDrawObj
);
102 mpFrame
= pFlyDrawObj
? pFlyDrawObj
->GetFlyFrame() : nullptr;
106 void SwAccessibleChild::Init( const SwFrame
* pFrame
)
113 void SwAccessibleChild::Init( vcl::Window
* pWindow
)
120 bool SwAccessibleChild::IsAccessible( bool bPagePreview
) const
126 bRet
= mpFrame
->IsAccessibleFrame() &&
127 ( !mpFrame
->IsCellFrame() ||
128 static_cast<const SwCellFrame
*>( mpFrame
)->GetTabBox()->GetSttNd() != nullptr ) &&
129 !mpFrame
->IsInCoveredCell() &&
131 !mpFrame
->IsPageFrame() );
133 else if ( mpDrawObj
)
145 bool SwAccessibleChild::IsBoundAsChar() const
151 bRet
= mpFrame
->IsFlyFrame() &&
152 static_cast< const SwFlyFrame
*>(mpFrame
)->IsFlyInContentFrame();
154 else if ( mpDrawObj
)
156 const SwFrameFormat
* pFrameFormat
= ::FindFrameFormat( mpDrawObj
);
158 && (RndStdIds::FLY_AS_CHAR
== pFrameFormat
->GetAnchor().GetAnchorId());
168 SwAccessibleChild
& SwAccessibleChild::operator=( const SdrObject
* pDrawObj
)
174 SwAccessibleChild
& SwAccessibleChild::operator=( const SwFrame
* pFrame
)
180 SwAccessibleChild
& SwAccessibleChild::operator=( vcl::Window
* pWindow
)
186 bool SwAccessibleChild::IsValid() const
188 return mpFrame
!= nullptr ||
189 mpDrawObj
!= nullptr ||
193 bool SwAccessibleChild::IsVisibleChildrenOnly() const
203 bRet
= mpFrame
->IsRootFrame() ||
204 !( mpFrame
->IsTabFrame() ||
205 mpFrame
->IsInTab() ||
207 static_cast<const SwFlyFrame
*>(mpFrame
)->GetAnchorFrame()->IsInTab() ) );
213 SwRect
SwAccessibleChild::GetBox( const SwAccessibleMap
& rAccMap
) const
219 if ( mpFrame
->IsPageFrame() &&
220 static_cast< const SwPageFrame
* >( mpFrame
)->IsEmptyPage() )
222 aBox
= SwRect( mpFrame
->getFrameArea().Left(), mpFrame
->getFrameArea().Top()-1, 1, 1 );
224 else if ( mpFrame
->IsTabFrame() )
226 aBox
= mpFrame
->getFrameArea();
227 aBox
.Intersection( mpFrame
->GetUpper()->getFrameArea() );
231 aBox
= mpFrame
->getFrameArea();
236 const SwContact
* const pContact
= ::GetUserCall(mpDrawObj
);
237 // assume that a) the SwVirt* objects that don't have this are handled
238 // by the mpFrame case above b) for genuine SdrObject this must be set
239 // if it's connected to layout
240 assert(dynamic_cast<SwDrawContact
const*>(pContact
));
241 SwPageFrame
const*const pPage(const_cast<SwAnchoredObject
*>(
242 pContact
->GetAnchoredObj(mpDrawObj
))->FindPageFrameOfAnchor());
243 if (pPage
) // may end up here with partial layout -> not visible
245 aBox
= SwRect( mpDrawObj
->GetCurrentBoundRect() );
246 // tdf#91260 drawing object may be partially off-page
247 aBox
.Intersection(pPage
->getFrameArea());
252 vcl::Window
*pWin
= rAccMap
.GetShell()->GetWin();
255 aBox
= SwRect( pWin
->PixelToLogic(
256 tools::Rectangle( mpWindow
->GetPosPixel(),
257 mpWindow
->GetSizePixel() ) ) );
264 SwRect
SwAccessibleChild::GetBounds( const SwAccessibleMap
& rAccMap
) const
270 if( mpFrame
->IsPageFrame() &&
271 static_cast< const SwPageFrame
* >( mpFrame
)->IsEmptyPage() )
273 aBound
= SwRect( mpFrame
->getFrameArea().Left(), mpFrame
->getFrameArea().Top()-1, 0, 0 );
276 aBound
= mpFrame
->GetPaintArea();
280 aBound
= GetBox( rAccMap
);
284 aBound
= GetBox( rAccMap
);
290 bool SwAccessibleChild::AlwaysIncludeAsChild() const
292 bool bAlwaysIncludedAsChild( false );
296 bAlwaysIncludedAsChild
= true;
299 return bAlwaysIncludedAsChild
;
302 const SwFrame
* SwAccessibleChild::GetParent( const bool bInPagePreview
) const
304 const SwFrame
* pParent( nullptr );
308 if( mpFrame
->IsFlyFrame() )
310 const SwFlyFrame
* pFly
= static_cast< const SwFlyFrame
*>( mpFrame
);
311 if( pFly
->IsFlyInContentFrame() )
313 // For RndStdIds::FLY_AS_CHAR the parent is the anchor
314 pParent
= pFly
->GetAnchorFrame();
315 OSL_ENSURE( SwAccessibleChild( pParent
).IsAccessible( bInPagePreview
),
316 "parent is not accessible" );
320 // In any other case the parent is the root frm
321 // (in page preview, the page frame)
323 pParent
= pFly
->FindPageFrame();
325 pParent
= pFly
->getRootFrame();
330 SwAccessibleChild
aUpper( mpFrame
->GetUpper() );
331 while( aUpper
.GetSwFrame() && !aUpper
.IsAccessible(bInPagePreview
) )
333 aUpper
= aUpper
.GetSwFrame()->GetUpper();
335 pParent
= aUpper
.GetSwFrame();
340 const SwDrawContact
*pContact
=
341 static_cast< const SwDrawContact
* >( GetUserCall( mpDrawObj
) );
342 OSL_ENSURE( pContact
, "sdr contact is missing" );
345 const SwFrameFormat
*pFrameFormat
= pContact
->GetFormat();
346 OSL_ENSURE( pFrameFormat
, "frame format is missing" );
347 if( pFrameFormat
&& RndStdIds::FLY_AS_CHAR
== pFrameFormat
->GetAnchor().GetAnchorId() )
349 // For RndStdIds::FLY_AS_CHAR the parent is the anchor
350 pParent
= pContact
->GetAnchorFrame();
351 OSL_ENSURE( SwAccessibleChild( pParent
).IsAccessible( bInPagePreview
),
352 "parent is not accessible" );
357 // In any other case the parent is the root frm
358 SwFrame
const*const pAnchor(pContact
->GetAnchorFrame());
359 if (pAnchor
) // null if object removed from layout
362 pParent
= pAnchor
->FindPageFrame();
364 pParent
= pAnchor
->getRootFrame();
371 css::uno::Reference
< css::accessibility::XAccessible
> xAcc
=
372 mpWindow
->GetAccessible();
375 css::uno::Reference
< css::accessibility::XAccessibleContext
> xAccContext
=
376 xAcc
->getAccessibleContext();
377 if ( xAccContext
.is() )
379 css::uno::Reference
< css::accessibility::XAccessible
> xAccParent
=
380 xAccContext
->getAccessibleParent();
381 if ( xAccParent
.is() )
383 SwAccessibleContext
* pAccParentImpl
=
384 dynamic_cast< SwAccessibleContext
*>( xAccParent
.get() );
385 if ( pAccParentImpl
)
387 pParent
= pAccParentImpl
->GetFrame();
397 } // namespace sw::access
399 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */