/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include "accfrmobj.hxx"
#include <accmap.hxx>
#include "acccontext.hxx"
#include <viewsh.hxx>
#include <rootfrm.hxx>
#include <flyfrm.hxx>
#include <pagefrm.hxx>
#include <cellfrm.hxx>
#include <swtable.hxx>
#include <dflyobj.hxx>
#include <frmfmt.hxx>
#include <fmtanchr.hxx>
#include <dcontact.hxx>
#include <vcl/window.hxx>
namespace sw::access {
SwAccessibleChild::SwAccessibleChild()
: mpFrame( nullptr )
, mpDrawObj( nullptr )
, mpWindow( nullptr )
{}
SwAccessibleChild::SwAccessibleChild( const SdrObject* pDrawObj )
: mpFrame( nullptr )
, mpDrawObj( nullptr )
, mpWindow( nullptr )
{
Init( pDrawObj );
}
SwAccessibleChild::SwAccessibleChild( const SwFrame* pFrame )
: mpFrame( nullptr )
, mpDrawObj( nullptr )
, mpWindow( nullptr )
{
Init( pFrame );
}
SwAccessibleChild::SwAccessibleChild( vcl::Window* pWindow )
: mpFrame( nullptr )
, mpDrawObj( nullptr )
, mpWindow( nullptr )
{
Init( pWindow );
}
SwAccessibleChild::SwAccessibleChild( const SwFrame* pFrame,
const SdrObject* pDrawObj,
vcl::Window* pWindow )
: mpFrame( nullptr )
, mpDrawObj( nullptr )
, mpWindow( nullptr )
{
if ( pFrame )
{
Init( pFrame );
}
else if ( pDrawObj )
{
Init( pDrawObj );
}
else if ( pWindow )
{
Init( pWindow );
}
OSL_ENSURE( (!pFrame || pFrame == mpFrame) &&
(!pDrawObj || pDrawObj == mpDrawObj) &&
(!pWindow || pWindow == mpWindow),
"invalid frame/object/window combination" );
}
SwAccessibleChild::~SwAccessibleChild() = default;
void SwAccessibleChild::Init( const SdrObject* pDrawObj )
{
mpDrawObj = pDrawObj;
const SwVirtFlyDrawObj* pFlyDrawObj = dynamic_cast<const SwVirtFlyDrawObj*>(mpDrawObj);
mpFrame = pFlyDrawObj ? pFlyDrawObj->GetFlyFrame() : nullptr;
mpWindow = nullptr;
}
void SwAccessibleChild::Init( const SwFrame* pFrame )
{
mpFrame = pFrame;
mpDrawObj = mpFrame && mpFrame->IsFlyFrame()
? static_cast < const SwFlyFrame * >( mpFrame )->GetVirtDrawObj()
: nullptr;
mpWindow = nullptr;
}
void SwAccessibleChild::Init( vcl::Window* pWindow )
{
mpWindow = pWindow;
mpFrame = nullptr;
mpDrawObj = nullptr;
}
bool SwAccessibleChild::IsAccessible( bool bPagePreview ) const
{
bool bRet( false );
if ( mpFrame )
{
bRet = mpFrame->IsAccessibleFrame() &&
( !mpFrame->IsCellFrame() ||
static_cast<const SwCellFrame *>( mpFrame )->GetTabBox()->GetSttNd() != nullptr ) &&
!mpFrame->IsInCoveredCell() &&
( bPagePreview ||
!mpFrame->IsPageFrame() );
}
else if ( mpDrawObj )
{
bRet = true;
}
else if ( mpWindow )
{
bRet = true;
}
return bRet;
}
bool SwAccessibleChild::IsBoundAsChar() const
{
bool bRet( false );
if ( mpFrame )
{
bRet = mpFrame->IsFlyFrame() &&
static_cast< const SwFlyFrame *>(mpFrame)->IsFlyInContentFrame();
}
else if ( mpDrawObj )
{
const SwFrameFormat* pFrameFormat = ::FindFrameFormat( mpDrawObj );
bRet = pFrameFormat
&& (RndStdIds::FLY_AS_CHAR == pFrameFormat->GetAnchor().GetAnchorId());
}
else if ( mpWindow )
{
bRet = false;
}
return bRet;
}
SwAccessibleChild& SwAccessibleChild::operator=( const SdrObject* pDrawObj )
{
Init( pDrawObj );
return *this;
}
SwAccessibleChild& SwAccessibleChild::operator=( const SwFrame* pFrame )
{
Init( pFrame );
return *this;
}
SwAccessibleChild& SwAccessibleChild::operator=( vcl::Window* pWindow )
{
Init( pWindow );
return *this;
}
bool SwAccessibleChild::IsValid() const
{
return mpFrame != nullptr ||
mpDrawObj != nullptr ||
mpWindow != nullptr;
}
bool SwAccessibleChild::IsVisibleChildrenOnly() const
{
bool bRet( false );
if ( !mpFrame )
{
bRet = true;
}
else
{
bRet = mpFrame->IsRootFrame() ||
!( mpFrame->IsTabFrame() ||
mpFrame->IsInTab() ||
( IsBoundAsChar() &&
static_cast<const SwFlyFrame*>(mpFrame)->GetAnchorFrame()->IsInTab() ) );
}
return bRet;
}
SwRect SwAccessibleChild::GetBox( const SwAccessibleMap& rAccMap ) const
{
SwRect aBox;
if ( mpFrame )
{
if ( mpFrame->IsPageFrame() &&
static_cast< const SwPageFrame * >( mpFrame )->IsEmptyPage() )
{
aBox = SwRect( mpFrame->getFrameArea().Left(), mpFrame->getFrameArea().Top()-1, 1, 1 );
}
else if ( mpFrame->IsTabFrame() )
{
aBox = mpFrame->getFrameArea();
aBox.Intersection( mpFrame->GetUpper()->getFrameArea() );
}
else
{
aBox = mpFrame->getFrameArea();
}
}
else if( mpDrawObj )
{
const SwContact* const pContact = ::GetUserCall(mpDrawObj);
// assume that a) the SwVirt* objects that don't have this are handled
// by the mpFrame case above b) for genuine SdrObject this must be set
// if it's connected to layout
assert(dynamic_cast<SwDrawContact const*>(pContact));
if (pContact)
{
SwPageFrame const*const pPage(const_cast<SwAnchoredObject *>(
pContact->GetAnchoredObj(mpDrawObj))->FindPageFrameOfAnchor());
if (pPage) // may end up here with partial layout -> not visible
{
aBox = SwRect( mpDrawObj->GetCurrentBoundRect() );
// tdf#91260 drawing object may be partially off-page
aBox.Intersection(pPage->getFrameArea());
}
}
}
else if ( mpWindow )
{
vcl::Window *pWin = rAccMap.GetShell()->GetWin();
if (pWin)
{
aBox = SwRect( pWin->PixelToLogic(
tools::Rectangle( mpWindow->GetPosPixel(),
mpWindow->GetSizePixel() ) ) );
}
}
return aBox;
}
SwRect SwAccessibleChild::GetBounds( const SwAccessibleMap& rAccMap ) const
{
SwRect aBound;
if( mpFrame )
{
if( mpFrame->IsPageFrame() &&
static_cast< const SwPageFrame * >( mpFrame )->IsEmptyPage() )
{
aBound = SwRect( mpFrame->getFrameArea().Left(), mpFrame->getFrameArea().Top()-1, 0, 0 );
}
else
aBound = mpFrame->GetPaintArea();
}
else if( mpDrawObj )
{
aBound = GetBox( rAccMap );
}
else if ( mpWindow )
{
aBound = GetBox( rAccMap );
}
return aBound;
}
bool SwAccessibleChild::AlwaysIncludeAsChild() const
{
bool bAlwaysIncludedAsChild( false );
if ( mpWindow )
{
bAlwaysIncludedAsChild = true;
}
return bAlwaysIncludedAsChild;
}
const SwFrame* SwAccessibleChild::GetParent( const bool bInPagePreview ) const
{
const SwFrame* pParent( nullptr );
if ( mpFrame )
{
if( mpFrame->IsFlyFrame() )
{
const SwFlyFrame* pFly = static_cast< const SwFlyFrame *>( mpFrame );
if( pFly->IsFlyInContentFrame() )
{
// For RndStdIds::FLY_AS_CHAR the parent is the anchor
pParent = pFly->GetAnchorFrame();
OSL_ENSURE( SwAccessibleChild( pParent ).IsAccessible( bInPagePreview ),
"parent is not accessible" );
}
else
{
// In any other case the parent is the root frm
// (in page preview, the page frame)
if( bInPagePreview )
pParent = pFly->FindPageFrame();
else
pParent = pFly->getRootFrame();
}
}
else
{
SwAccessibleChild aUpper( mpFrame->GetUpper() );
while( aUpper.GetSwFrame() && !aUpper.IsAccessible(bInPagePreview) )
{
aUpper = aUpper.GetSwFrame()->GetUpper();
}
pParent = aUpper.GetSwFrame();
}
}
else if( mpDrawObj )
{
const SwDrawContact *pContact =
static_cast< const SwDrawContact* >( GetUserCall( mpDrawObj ) );
OSL_ENSURE( pContact, "sdr contact is missing" );
if( pContact )
{
const SwFrameFormat *pFrameFormat = pContact->GetFormat();
OSL_ENSURE( pFrameFormat, "frame format is missing" );
if( pFrameFormat && RndStdIds::FLY_AS_CHAR == pFrameFormat->GetAnchor().GetAnchorId() )
{
// For RndStdIds::FLY_AS_CHAR the parent is the anchor
pParent = pContact->GetAnchorFrame();
OSL_ENSURE( SwAccessibleChild( pParent ).IsAccessible( bInPagePreview ),
"parent is not accessible" );
}
else
{
// In any other case the parent is the root frm
SwFrame const*const pAnchor(pContact->GetAnchorFrame());
if (pAnchor) // null if object removed from layout
{
if (bInPagePreview)
pParent = pAnchor->FindPageFrame();
else
pParent = pAnchor->getRootFrame();
}
}
}
}
else if ( mpWindow )
{
css::uno::Reference < css::accessibility::XAccessible > xAcc =
mpWindow->GetAccessible();
if ( xAcc.is() )
{
css::uno::Reference < css::accessibility::XAccessibleContext > xAccContext =
xAcc->getAccessibleContext();
if ( xAccContext.is() )
{
css::uno::Reference < css::accessibility::XAccessible > xAccParent =
xAccContext->getAccessibleParent();
if ( xAccParent.is() )
{
SwAccessibleContext* pAccParentImpl =
dynamic_cast< SwAccessibleContext *>( xAccParent.get() );
if ( pAccParentImpl )
{
pParent = pAccParentImpl->GetFrame();
}
}
}
}
}
return pParent;
}
} // namespace sw::access
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V530 The return value of function 'Intersection' is required to be utilized.
↑ V530 The return value of function 'Intersection' is required to be utilized.